Ruby的哈希数组,比较2个键并加上另一个键/值

Nic*_*ick 2 ruby arrays hash

在Ruby中我有以下哈希数组:

[
  {:qty => 1, :unit => 'oz', :type => 'mass'},
  {:qty => 5, :unit => 'oz', :type => 'vol'},
  {:qty => 4, :unit => 'oz', :type => 'mass'},
  {:qty => 1, :unit => 'lbs', :type => 'mass'}
]
Run Code Online (Sandbox Code Playgroud)

我需要做的是通过:unit和比较元素:type,然后求:qty它们相同的时间.生成的数组应如下所示:

[
  {:qty => 5, :unit => 'oz', :type => 'mass'},
  {:qty => 5, :unit => 'oz', :type => 'vol'},
  {:qty => 1, :unit => 'lbs', :type => 'mass'}
]
Run Code Online (Sandbox Code Playgroud)

如果数组有多个哈希,其中:qtyis nil:unit是空(""),那么它只会返回其中一个.所以为了扩展上面的例子,这个:

[
  {:qty => 1, :unit => 'oz', :type => 'mass'},
  {:qty => nil, :unit => '', :type => 'Foo'},
  {:qty => 5, :unit => 'oz', :type => 'vol'},
  {:qty => 4, :unit => 'oz', :type => 'mass'},
  {:qty => 1, :unit => 'lbs', :type => 'mass'},
  {:qty => nil, :unit => '', :type => 'Foo'}
]
Run Code Online (Sandbox Code Playgroud)

会成为这样的:

[
  {:qty => 5, :unit => 'oz', :type => 'mass'},
  {:qty => nil, :unit => '', :type => 'Foo'},
  {:qty => 5, :unit => 'oz', :type => 'vol'},
  {:qty => 1, :unit => 'lbs', :type => 'mass'}
]
Run Code Online (Sandbox Code Playgroud)

编辑:对不起,在第二个例子中犯了一个错误......它不应该有o.

And*_*all 8

首先使用group_by您想要的键,然后reduceqty每个值中的s转换为单个散列,或者使用nil它们全部nil:

properties.group_by do |property|
  property.values_at :type, :unit
end.map do |(type, unit), properties|
  quantities = properties.map { |p| p[:qty] }
  qty = quantities.all? ? quantities.reduce(:+) : nil
  { type: type, unit: unit, qty: qty }
end

#=> [{:type=>"mass", :unit=>"oz", :qty=>5},
#    {:type=>"Foo", :unit=>"", :qty=>nil},
#    {:type=>"vol", :unit=>"oz", :qty=>5},
#    {:type=>"mass", :unit=>"lbs", :qty=>1}]
Run Code Online (Sandbox Code Playgroud)

properties您的第二个样本输入数据在哪里.