6

I want to find unique elements from an array of arrays by the first element in the inner arrays.

for example

a = [[1,2],[2,3],[1,5]

I want something like

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

2 Answers 2

14

The uniq method takes a block:

uniq_a = a.uniq(&:first)

Or if you want to do it in-place:

a.uniq!(&:first)

For example:

>> a = [[1,2],[2,3],[1,5]]
=> [[1, 2], [2, 3], [1, 5]]
>> a.uniq(&:first)
=> [[1, 2], [2, 3]]
>> a
=> [[1, 2], [2, 3], [1, 5]]

Or

>> a = [[1,2],[2,3],[1,5]]
=> [[1, 2], [2, 3], [1, 5]]
>> a.uniq!(&:first)
=> [[1, 2], [2, 3]]
>> a
=> [[1, 2], [2, 3]]

If you're stuck back in 1.8.7 land where uniq doesn't take a block, then you can do it this way:

a.group_by(&:first).values.map(&:first)

For example:

>> a = [[1,2],[2,3],[1,5]]
=> [[1, 2], [2, 3], [1, 5]]
>> a.group_by(&:first).values.map(&:first)
=> [[1, 2], [2, 3]]

Thanks for the extra prodding Jin.

Sign up to request clarification or add additional context in comments.

2 Comments

Note: I was trying this out in 1.8.7 and wondered why it wasn't working. Found out that passing a block to uniq was added in Ruby 1.9.2, as stated here. rbjl.net/….
@Jin: Right, I added a 1.8.7 compatible version for you :)
1

Here's a ruby 1.8.7 solution

irb> [[1,2],[2,3],[1,5]].inject([]) { |memo,x| memo << x unless memo.detect { |item| item.first == x.first }; memo }
=> [[1, 2], [2, 3]]

You could also take the shorthand over a hash and be a bit lazy and take the last item instead

irb> [[1,2],[2,3],[1,5]].inject({}) { |memo,x| memo[x.first] = x; memo }.map { |x| x.last }
=> [[1, 5], [2, 3]]

1 Comment

Something like [[1,2],[2,3],[1,5]].inject({}) { |memo,x| memo[x.first] ||= x; memo }.values would be another option (since we're only dealing with numbers in the arrays) and would probably faster than my fancy 1.8.7 version (not that the speed difference would matter much of course).

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.