Vyacheslav Loginov
Vyacheslav Loginov

Reputation: 3216

ruby sum values in array by keys

How to sum

[["a", 1], ["b", 2], ["c", 3], ["a", 20], ["b", 12], ["c", 5]]

into

[["a", 21], ["b", 14], ["c", 8]]

I don't understand how to combine array map by keys with inject(&:+) by value in such keys

Upvotes: 1

Views: 474

Answers (5)

Cary Swoveland
Cary Swoveland

Reputation: 110675

arr = [["a", 1], ["b", 2], ["c", 3], ["a", 20], ["b", 12], ["c", 5]]

arr.group_by(&:first).map { |k,v| [k,v.transpose.last.reduce(:+)]}     
  #=> [["a", 21], ["b", 14], ["c", 8]] 

Upvotes: 2

bjhaid
bjhaid

Reputation: 9752

arr = [["a", 1], ["b", 2], ["c", 3], ["a", 20], ["b", 12], ["c", 5]]

arr.each_with_object(Hash.new(0)) { |x,hsh| hsh[x[0]] += x[1] }.to_a
# => [["a", 21], ["b", 14], ["c", 8]]

Upvotes: 2

Rafa Paez
Rafa Paez

Reputation: 4860

My functional solution

array = [["a", 1], ["b", 2], ["c", 3], ["a", 20], ["b", 12], ["c", 5]]

array.group_by do |a|
  a.first
end.map do |k, v|
  [k, v.reduce(0) { |acc, (l, r)| acc + r }]
end
# => [["a", 21], ["b", 14], ["c", 8]] 

Upvotes: 2

Mori
Mori

Reputation: 27779

x = [["a", 1], ["b", 2], ["c", 3], ["a", 20], ["b", 12], ["c", 5]]
y = Hash.new(0)
x.each {|a| y[a[0]] += a[1]}
y.to_a

=> [["a", 21], ["b", 14], ["c", 8]]

Upvotes: 2

Victor Moroz
Victor Moroz

Reputation: 9225

.group_by(&:first).map { |k, v| [k, v.map(&:last).inject(:+)] }

Upvotes: 6

Related Questions