Abhishek Patel
Abhishek Patel

Reputation: 138

uniq elements from array of arrays

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]]

Upvotes: 6

Views: 4018

Answers (2)

sunkencity
sunkencity

Reputation: 3472

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]]

Upvotes: 1

mu is too short
mu is too short

Reputation: 434665

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.

Upvotes: 14

Related Questions