9

I'm executing an active record command Product.pluck(:category_id, :price), which returns an array of 2 element arrays:

[
  [1, 500],
  [1, 100],
  [2, 300]
]

I want to group on the basis of the first element, creating a hash that looks like:

{1 => [500, 100], 2 => [300]}

group_by seems logical, but replicates the entire array. I.e. a.group_by(&:first) produces:

{1=>[[1, 500], [1, 100]], 2=>[[2, 300]]}
0

5 Answers 5

20

You can do a secondary transform to it:

Hash[
  array.group_by(&:first).collect do |key, values|
    [ key, values.collect { |v| v[1] } ]
  end
]

Alternatively just map out the logic directly:

array.each_with_object({ }) do |item, result|
  (result[item[0]] ||= [ ]) << item[1]
end
Sign up to request clarification or add additional context in comments.

1 Comment

Wow. I love this construct
5

This one-liner seemed to work for me.

array.group_by(&:first).map { |k, v| [k, v.each(&:shift)] }.to_h

Comments

3

Since you're grouping by the first element, just remove it with shift and turn the result into a hash:

array.group_by(&:first).map do |key, value|
  value = value.flat_map { |x| x.shift; x }
  [key, value]
end #=> {1=>[500, 100], 2=>[300]}

1 Comment

This made sense as well, I went with each_with_object since it avoided hashification
2

I do not like the destructive operation.

array.group_by(&:first).map { |id, a| [id, a.map(&:last)] }.to_h

Comments

0

Used this functionality several times in my app, added extension to an array:

# config/initializers/array_ext.rb
class Array
  # given an array of two-element arrays groups second element by first element, eg:
  # [[1, 2], [1, 3], [2, 4]].group_second_by_first #=> {1 => [2, 3], 2 => [4]}
  def group_second_by_first
    each_with_object({}) { |(first, second), h| (h[first] ||= []) << second }
  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.