2

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"]
7
  • 4
    what do you want the end result to be? an array of arrays? or a single array? If the end result is just a single array then @newmediafreak's answer is probably what you want Commented May 1, 2015 at 19:32
  • I want a single array of uniq elements. @newmediafreak's answer is right. But need 4 mins more to mark it as accepted.! Commented May 1, 2015 at 19:40
  • 1
    Do you want [[1,2,2],[2,1,2]] => [1,2]` and [[1,2,2],[2,1,3]] => [1,2,3], or [[1,2,2],[2,1,2]]` => [1,2,2]` and [[1,2,2],[2,1,3]] => [[1,2,2],[2,1,3]], or something else? Please answer by editing the question, rather than explaining in comments. Commented May 1, 2015 at 19:44
  • 1
    I suggest that in future you hold off awhile before selecting your preferred answer. Doing so discourages other answers and is inconsiderate to others who are still working on their answers. Many SO members wait a couple of hours or more before making a selection. There's no rush, just don't forget. Commented May 1, 2015 at 19:47
  • @CarySwoveland: I agree with you. Thank you for your guidance. Commented May 1, 2015 at 19:49

3 Answers 3

11

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"]
Sign up to request clarification or add additional context in comments.

Comments

3

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.