Liz
Liz

Reputation: 1447

Ruby: Use Nested Arrays to Compile Values with Similar First Item

I have a Ruby nested array like this:

arr = [["Red", 2], ["Red", 1], ["Yellow", 0], ["Yellow", 2], ["Blue", 1]]

And I'm trying to find a method that adds up the number (which is the second item in each mini-array) for similar items, yielding a nested array like this:

[["Red", 3], ["Yellow", 2], ["Blue", 1]]

I've tried for loops, and if statements, but I can't figure out exactly how to do it.

With a non-nested array you could just use if and .includes?, but I'm not sure how to work that with a nested array.

Any Ruby wizards able to steer me in the right direction here?

Upvotes: 0

Views: 75

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110725

arr.each_with_object(Hash.new(0)) {|(col,nbr),h| h[col] += nbr}.to_a
  #=> [["Red", 3], ["Yellow", 2], ["Blue", 1]]

Note the intermediate calculation:

arr.each_with_object(Hash.new(0)) {|(col,nbr),h| h[col] += nbr}
  #=> {"Red"=>3, "Yellow"=>2, "Blue"=>1}

See Hash::new.

Upvotes: 1

Ursus
Ursus

Reputation: 30071

Note that this is not an array nor valid ruby

["Red", 3], ["Yellow", 2], ["Blue", 1]

anyway try this

arr.group_by { |color, amount| color }
   .map { |k, color_arr| [k, color_arr.map(&:last).inject(:+)] }
 => [["Red", 3], ["Yellow", 2], ["Blue", 1]]

or from ruby 2.4.0 and upwards

arr.group_by { |color, amount| color }
   .map { |k, color_arr| [k, color_arr.map(&:last).sum] }

Upvotes: 2

Related Questions