Ahmad hamza
Ahmad hamza

Reputation: 1936

Remove duplicates from an array of array

How do I remove duplicates from this array?

product_areas = [["1", "2", "3"], ["3", "1", "2"]]

I have tried product_areas.uniq!, product_area.uniq but the same thing is repeating. What am I missing here?

Expected Output:

product_areas = ["1", "2", "3"]

Upvotes: 2

Views: 2007

Answers (3)

Steve Craig
Steve Craig

Reputation: 461

I've used this little snippet of code over and over again in my career as a Ruby on Rails developer to solve this frequently encountered problem in a single piece of neat little code. The end result of this code is that you can just call something like

product_areas.squish

to do the following:

  1. flatten 2-D arrays into 1-D arrays
  2. remove nil elements
  3. remove duplicate elements

I do this by adding an initializer config/initializer/core_ext.rb to my project which extends the core Ruby functionality as follows:

class Array
  def squish
      blank? ? [] : flatten.compact.uniq
  end
end

class NilClass
  def squish
      []
  end
end

Upvotes: 0

tykowale
tykowale

Reputation: 449

As previously pointed out

product_areas = [["1", "2", "3"], ["3", "1", "2"]].flatten.uniq

-OR-

product_areas.flatten.uniq!

will both lead you to your desired answer.

Why?

When you were running "product_areas.uniq!" the process was comparing the two inner arrays against each other, other than the elements of each array. Because both ["1", "2", "3"] and ["3", "1", "2"] are unique in the array, neither will be removed. As an example say you had the following array

product_areas = [["1", "2", "3"], ["3", "1", "2"], ["1","2","3"]]

and you ran:

product_areas = product_areas.uniq

product_areas would then look like the following:

product_areas = [["1", "2", "3"], ["3", "1", "2"]]

What you need to be aware of when running any sort of enumerable method on arrays is it will only move down to each individual element. So if inside an array you have more arrays, any iterative method will look at the inner array as a whole. Some sample code to demonstrate this:

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

array_of_arrays.each do |array|
  p array
end
#---OUPUT---
# [1, 2, 3]
# [4, 5, 6]

array_of_arrays.each do |array|
  array.each do |element|
    p element
  end
end
#---OUPUT---
# 1
# 2
# 3
# 4
# 5
# 6

Upvotes: 3

Kevin
Kevin

Reputation: 1223

Try this:

product_areas = [["1", "2", "3"], ["3", "1", "2"]].flatten.uniq

Using flatten on your array will create the following result:

["1", "2", "3", "3", "1", "2"]

When you call uniq on that array, you will get the result you were expecting:

["1", "2", "3"]

Upvotes: 11

Related Questions