endex
endex

Reputation: 123

Ruby: Remove all instances of a duplicate value inside an array

I have one array and I want to remove ALL instances of a duplicate value inside of that array.

arr = [1, 1, 2, 3, 4, 4, 5]

I want the expected output:

=> [2, 3, 5]

What would be the best way to do this?

Upvotes: 4

Views: 1429

Answers (6)

StarPerfect
StarPerfect

Reputation: 11

There is a much simpler solution:

arr = [1, 2, 1, 3, 1, 4, 1, 5, 1, 6]

new_arr = arr - [1]

new_arr returns [2, 3, 4, 5, 6]

Upvotes: 1

Fawwaz Fauzi Mahfuzh
Fawwaz Fauzi Mahfuzh

Reputation: 11

arr = [1, 1, 2, 3, 4, 4, 5]
arr.reject{|x| arr.count(x)>1}

expected output

=> [2, 3, 5]

if it's a Multi-dimensional

multi_array = [[33], [34], [35], [34, 35], [34, 35], [36], [30, 31], [30, 31], [30, 31, 32], [32, 33]] 
multi_flatten = multi_array.flatten
#=> [33, 34, 35, 34, 35, 34, 35, 36, 30, 31, 30, 31, 30, 31, 32, 32, 33]
multi_flatten.reject{|x| multi_flatten.count(x)>1}
#=> [36]

Upvotes: 1

rahul mishra
rahul mishra

Reputation: 1470

enter image description here

+1 for: arr.uniq.select { |n| arr.count(n) == 1 } seems to be more readable and clean

@cary-swoveland Array#difference seem to have some performance issue.

Upvotes: 0

Cary Swoveland
Cary Swoveland

Reputation: 110675

Here are three ways that could be done (@Rajagopalan's answer being another).

arr = [1, 1, 2, 3, 4, 4, 5]

Use a counting hash

arr.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }.select { |_,v| v == 1 }.keys
  # => [2, 3, 5]

Use Array#count

arr.uniq.select { |n| arr.count(n) == 1 }
  #=> [2, 3, 5]

This may seem relatively inefficient considering that arr must be traversed for each element of arr.uniq. If arr.uniq is not too large, however, it actually may be faster than using a counting hash or (as Rajagopalan has done) Enumerable#group_by.

Use Array#difference

Array#difference is a method I have suggested be added to the Ruby core.

class Array
  def difference(other)
    h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
    reject { |e| h[e] > 0 && h[e] -= 1 }
  end
end

If we had use of that method we could write the following.

arr - arr.difference(arr.uniq)
  #=> [2, 3, 5] 

Upvotes: 3

Rajagopalan
Rajagopalan

Reputation: 6064

p arr.group_by(&:itself).reject{|k,v|v.count>1}.keys

Output

[2, 3, 5]

Upvotes: 7

Mark
Mark

Reputation: 6445

https://apidock.com/ruby/Array/uniq

arr = [1, 1, 2, 3, 4, 4, 5]
arr.uniq 

returns

[1, 2, 3, 4, 5]

Upvotes: -2

Related Questions