The cryptic Ruby function takes an array as an argument and returns an array of the items that occur more than once in the original array.
It does this using the inject
method specifying an empty Hash as the accumulator. It iterates over each item in the array by referencing the item index position, and passes the resulting item into the accumulator. This builds up a hash of key/value pairs with the key being the item from the initial collection and the value representing the number of times the item appears in the array. It then uses the reject
method on the resulting hash and iterates over the hash returning a new array containing the items in self
for which the given block is false.
Using idiomatic Ruby a cleaner way to write this function would be:
def show_duplicates(collection)
collection.select { |element| collection.count(element) > 1 }.uniq
end
Notes:
-
Testing: Since this is a refactoring exercise, it is important to write tests to make sure that expected behavior does not change during the refactor. While refactoring I expanded the original function using meaningful method & variable names as an intermediate step. I ran all of these against a small test suite. For the sake of completeness these files are available as a GitHub Gist at: http://cl.ly/aXJ4
-
Performance: The original function appears to be linear, i.e. O(2n), while the refactored example is, I believe, exponential, i.e. O(n^2 + n). Depending on the use case, this may be an important consideration.