Consolidating duplicate array items

2019-03-06 12:32发布

问题:

I have an array of hashes...

array = [
{
    'keyword' => 'A',
    'total_value' => 50
},
{
    'keyword' => 'B',
    'total_value' => 25
},
{
    'keyword' => 'C',
    'total_value' => 40
},
{
    'keyword' => 'A',
    'total_value' => 10
},
{
    'keyword' => 'C',
    'total_value' => 15
}]

I need to consolidate the hashes with an identical keyword value. By consolidate, I mean combine total_values. For example, after consolidation of the above array, there should only be one hash with 'keyword' => 'A' with a 'total_value => 60

回答1:

array =  [
{
    'keyword' => 'A',
    'total_value' => 50
},
{
    'keyword' => 'B',
    'total_value' => 25
},
{
    'keyword' => 'C',
    'total_value' => 40
},
{
    'keyword' => 'A',
    'total_value' => 10
},
{
    'keyword' => 'C',
    'total_value' => 15
}]

m = array.inject(Hash.new(0)) do |hs,i| 
    hs[i['keyword']] += i['total_value'] 
    hs 
end
p m

Output:

{"A"=>60, "B"=>25, "C"=>55}

By consolidate, I mean combine total_values. For example, after consolidation of the above array, there should only be one hash with 'keyword' => 'A' with a 'total_value => 60

Here is how it can be done:

m = array.each_with_object(Hash.new(0)) do |h,ob| 
     if h['keyword'] == 'A'
        h['total_value'] += ob['total_value']
        ob.update(h)
     end
end
p m
#=> {"keyword"=>"A", "total_value"=>60}


回答2:

A simple method is doing this as you add items to a collection. Start to add an item, check if keyword is there. if (a) it's there, then just add new item's total_value to its. else (b) add new item to the collection.



回答3:

array.group_by{|h| h["keyword"]}
.map{|k, v| {
  "keyword" => k,
  "total_value" => v.map{|h| h["total_value"]}.inject(:+)
}}


标签: ruby arrays hash