How to condense summable metrics to a unique identifier in a ruby table
I think the other answerers are overthinking this. You can do this with just one operation, each_with_object
, and a Hash:
metrics = [["id1", 123], ["id2", 234], ["id1", 345]]
metrics.each_with_object(Hash.new(0)) do |(id, val), sums|
sums[id] += val
end
# => {"id1"=>468, "id2"=>234}
If you want an Array instead of a Hash at the end just call to_a
on the result, but there are few compelling reasons to do so.
How to sum multiple elements of nested arrays on unique keys
This is essentially the same as the solution to your previous question.
data = [ [ 123.0, 23, "id1", 34, "abc" ],
[ 234.1, 43, "id2", 24, "jsk" ],
[ 423.5, 53, "id1", 1, "xyz" ],
[ 1.4, 5, "id2", 0, "klm" ] ]
sums = Hash.new {|h,k| h[k] = [0, 0, 0] }
data.each_with_object(sums) do |(val0, val1, id, val2, _), sums|
sums[id][0] += val0
sums[id][1] += val1
sums[id][2] += val2
end
# => { "id1" => [ 546.5, 76, 35 ],
# "id2" => [ 235.5, 48, 24 ] }
The main difference is that instead of giving the Hash a default value of 0
, we're giving it a default proc that initializes missing keys with [0, 0, 0]
. (We can't just do Hash.new([0, 0, 0])
because then every value would be a reference to a single Array instance, rather than each value having its own Array.) Then, inside the block, we add each value (val0
et al) to the corresponding elements of sums[id]
.
If you wanted an Array of Arrays instead of a Hash with the id
at index 2, then at the end, you would have to add something like this:
.map {|id, vals| vals.insert(2, id) }
However, a Hash with the ids as keys makes more sense as a data structure.
Related Topics
Error Loading the 'Sqlite3' Active Record Adapter. When I Deploy in Heroku
Why Sinatra Request Takes Em Thread
How to Write a Method That Counts the Most Common Substring in a String in Ruby
Devise 'Find_First_By_Auth_Conditions' Method Explanation
Ruby Selenium Web Drive: How to Find Specific Element by Xpath Div Id and CSS Class
Regex to Remove the Webpage Part of a Url in Ruby
Making a Pie-Chart of the User Age in Rails
Extract Text Between Two Tags Using Regex in Ruby
How to Ignore Irrelevant Methods When Profiling Ruby Applications
Why Does 'Defined' Return a String or Nil
When Passing a Ruby Array as an Argument, Why Does '<<' Append While '+=' Does Not
How to Use Link_To with Ajax in Rails 3.2.1
Converting Colors (Not Images) with Imagemagick
How to Run Code After Ruby Kernel.Exec
How to Send Notifications to the User Whose Post Received a Comment