Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping an array on the basis of its first element, without duplication in Ruby

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]]}
like image 795
Allyl Isocyanate Avatar asked Oct 28 '14 19:10

Allyl Isocyanate


3 Answers

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
like image 182
tadman Avatar answered Nov 07 '22 14:11

tadman


This one-liner seemed to work for me.

array.group_by(&:first).map { |k, v| [k, v.each(&:shift)] }.to_h
like image 4
inket Avatar answered Nov 07 '22 12:11

inket


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]}
like image 3
daremkd Avatar answered Nov 07 '22 12:11

daremkd