How to find and return a duplicate value in array
a = ["A", "B", "C", "B", "A"]
a.detect{ |e| a.count(e) > 1 }
I know this isn't very elegant answer, but I love it. It's beautiful one liner code. And works perfectly fine unless you need to process huge data set.
Looking for faster solution? Here you go!
def find_one_using_hash_map(array)
map = {}
dup = nil
array.each do |v|
map[v] = (map[v] || 0 ) + 1
if map[v] > 1
dup = v
break
end
end
return dup
end
It's linear, O(n), but now needs to manage multiple lines-of-code, needs test cases, etc.
If you need an even faster solution, maybe try C instead.
And here is the gist comparing different solutions: https://gist.github.com/naveed-ahmad/8f0b926ffccf5fbd206a1cc58ce9743e
Simply find the first instance where the index of the object (counting from the left) does not equal the index of the object (counting from the right).
arr.detect {|e| arr.rindex(e) != arr.index(e) }
If there are no duplicates, the return value will be nil.
I believe this is the fastest solution posted in the thread so far, as well, since it doesn't rely on the creation of additional objects, and #index
and #rindex
are implemented in C. The big-O runtime is N^2 and thus slower than Sergio's, but the wall time could be much faster due to the the fact that the "slow" parts run in C.
You can do this in a few ways, with the first option being the fastest:
ary = ["A", "B", "C", "B", "A"]
ary.group_by{ |e| e }.select { |k, v| v.size > 1 }.map(&:first)
ary.sort.chunk{ |e| e }.select { |e, chunk| chunk.size > 1 }.map(&:first)
And a O(N^2) option (i.e. less efficient):
ary.select{ |e| ary.count(e) > 1 }.uniq