Vlad
Vlad

Reputation: 256

Ruby grouping elements

I have array:

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

And I want to group by values, but save it indexes, so result must be looks like this:

[[0, 2, 5], [1, 3], [4, 6]]

or hash

{1=>[0, 2, 5], 3=>[1, 3], 2=>[4, 6]} 

Now I'm using pretty ugly and big code:

struc = Struct.new(:index, :value)
array = array.map.with_index{ |v, i| struc.new(i, v) }.group_by {|s| s[1]}.map { |h| h[1].map { |e| e[0]}}

`

Upvotes: 0

Views: 67

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110755

You can use:

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

a.each_with_index.group_by(&:first).values.map { |b| b.transpose.last }
  #=> [[0, 2, 5], [1, 3], [4, 6]] 

Upvotes: 0

August
August

Reputation: 12568

a = [1, 3, 1, 3, 2, 1, 2]
a.each_with_index.group_by(&:first).values.map { |h| h.map &:last }

First we get an Enumerator in the form [val, idx], ... (each_with_index), then group_by the value (first value in pair), then take the index (last element) of each pair.

Upvotes: 2

spickermann
spickermann

Reputation: 107107

If you use a hash with a default value to avoid iterating twice over the elements:

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

Hash.new { |h, k| h[k] = [] }.tap do |result|
  a.each_with_index { |i, n| result[i] << n }
end
#=> { 1 => [0, 2, 5], 3 => [1, 3], 2 => [4, 6] }

Upvotes: 2

Related Questions