3

Either I don't understand what happens when you subtract an array from an array, or something is wrong here.

What I have is a list of usernames (strings) in an array:

users.count - users.uniq.count    # => 9
users - users.uniq                # => []

I'm not sure how this is possible.

I'm essentially trying to find a list of the duplicates. I realize there are other ways to go about this, just trying to understand Array operations better.

Here is the workaround code I used to get the same:

users.inject(Hash.new(0)) {|h,i| h[i] += 1; h}.select{|k,v| v > 1}
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
BaroldGene
  • 220
  • 2
  • 8

2 Answers2

7

You could use

dups = users.select{|e| users.count(e) > 1 }.uniq

Or, to find only a single duplicate element:

firstDup = users.detect {|e| users.count(e) > 1 }

About the array subtraction, this may clarify:

a = [1, 1, 1, 1, 1]
a - [1] # => []

Array subraction removes all occurences, not just one.

tckmn
  • 57,719
  • 27
  • 114
  • 156
4

The behavior of Array#- is quite correct. It

Returns a new array that is a copy of the original array, removing any items that also appear in other_ary.

The user list (with duplicates) without all the users is empty.

Coming from "Ruby: How to find and return a duplicate value in array?", the following seems to be good at finding duplicates in an Array:

users.detect {|e| users.rindex(e) != users.index(e) }
Community
  • 1
  • 1
tessi
  • 13,313
  • 3
  • 38
  • 50
  • Just to increase performance by only doing 1 search: ``` users.select.with_index { |e,i| users.rindex(e) != i } ``` And if the index also needed then ``` users.each.with_index.select { |e,i| users.rindex(e) != i } ``` – Kaplan Ilya Nov 05 '20 at 12:14