Last active
April 11, 2017 19:14
-
-
Save shipstar/653710de2f1179b0e70b to your computer and use it in GitHub Desktop.
Kyle's solutions to Winston's thing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def find_duplicates(arr) | |
arr \ | |
.group_by(&:itself) | |
.map { |el, appearances| el if appearances.size > 1 } | |
.compact | |
end | |
# Walkthrough: | |
# 1. [1,2,2,3,3,3].group_by(&:itself) | |
# => { 1 => [1], 2 => [2,2], 3 => [3,3,3] } | |
# 2. map the key if there are multiple appearances, nil if only one appearance | |
# 3. compact removes any nils that were mapped in step 2 | |
# Interesting bits: | |
# 1. I didn't know :itself was a method now. | |
# 2. Requires two passes (map and compact) | |
# which could be sub-optimal on large data sets | |
# (although compact seems pretty performant). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# To avoid the two-pass issue from above, we need something that only adds | |
# to the array if the value isn't nil. | |
# compact_map seems like a good name, and it turns out there's a proposal for it: | |
# https://bugs.ruby-lang.org/issues/5663 | |
# I would only monkey patch this if: | |
# | |
# 1. I was using it in many places. | |
# 2. Performance isn't worse than map.compact, | |
# since this is in Ruby and that's probably in C. | |
# | |
# If not #1 and #2, I'd probably just leave it as-is. | |
module Enumerable | |
# Much like map, we need to allow transformations here: | |
# { 1 => 2, 3 => nil, 4 => 5 }.compact_map { |k,v| k * 9 if v } | |
# => [9, 36] | |
# It should also return the original enumerable if called without a block: | |
# { 1 => 2, 3 => nil, 4 => 5 }.compact_map | |
# (Currently mine returns the equivalent of hash.map.to_a | |
# instead of an enumerable. Should probably fix that before production.) | |
def compact_map | |
inject([]) do |memo, val| | |
transformed = block_given? ? yield(val) : val | |
memo << transformed if transformed | |
memo | |
end | |
end | |
end | |
def find_duplicates(arr) | |
arr \ | |
.group_by(&:itself) | |
.compact_map { |el, appearances| el if appearances.size > 1 } | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment