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"}
]
私ができるようにする必要があるのは、 :unit
そして :type
そして合計する :qty
それらが同じ場合。結果の配列は次のようになります。
[
{:qty => 5, :unit => "oz", :type => "mass"},
{:qty => 5, :unit => "oz", :type => "vol"},
{:qty => 1, :unit => "lbs", :type => "mass"}
]
配列に複数のハッシュがある場合、 :qty
は nil
そしてその :unit
空です(""
)、それらのうちの1つのみを返します。したがって、上記の例を拡張するには、次のようにします。
[
{: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"}
]
これになるだろう:
[
{:qty => 5, :unit => "oz", :type => "mass"},
{:qty => nil, :unit => "", :type => "Foo"},
{:qty => 5, :unit => "oz", :type => "vol"},
{:qty => 1, :unit => "lbs", :type => "mass"}
]
編集:申し訳ありませんが、2番目の例でミスを犯しました...それはoを持っているべきではありません。
回答:
回答№1は8を使って開始 group_by
必要なキーを使用して、 reduce
その qty
s各値を1つのハッシュにするか、代わりに 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}]
どこで properties
2番目のサンプル入力データです。
回答№2の場合は3
あなたが欲しい」 enumberable.group_by
これはあなたが始めるはずです
items.group_by { |item| item.values_at(:unit, :type) }
出力
{
["oz", "mass"]=> [
{:qty=>1, :unit=>"oz", :type=>"mass"},
{:qty=>4, :unit=>"oz", :type=>"mass"}
],
["oz", "vol"]=>[
{:qty=>5, :unit=>"oz", :type=>"vol"}
],
["lbs", "mass"]=>[
{:qty=>1, :unit=>"lbs", :type=>"mass"}
]
}
回答№3の場合は-1
ar = [{: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 => "o", :type => "Foo"}]
result = ar.each_with_object(Hash.new(0)) do |e,hsh|
if hsh.has_key?({:unit => e[:unit], :type => e[:type]})
hsh[{:unit => e[:unit], :type => e[:type]}] += e[:qty]
else
hsh[{:unit => e[:unit], :type => e[:type]}] = e[:qty]
end
end
result.map{|k,v| k[:qty] = v;k }.delete_if{|h| h[:qty].nil? and !h[:unit].empty? }
# => [{:unit=>"oz", :type=>"mass", :qty=>5},
# {:unit=>"", :type=>"Foo", :qty=>nil},
# {:unit=>"oz", :type=>"vol", :qty=>5},
# {:unit=>"lbs", :type=>"mass", :qty=>1}]
取る @アンドリューマーシャル 検討中の
ar = [{: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 => "o", :type => "Foo"}]
result = ar.each_with_object(Hash.new(0)) do |e,hsh|
if hsh.has_key?({:unit => e[:unit], :type => e[:type]})
hsh[{:unit => e[:unit], :type => e[:type]}] += e[:qty]
else
hsh[{:unit => e[:unit], :type => e[:type]}] = e[:qty]
end
end
result.map{|k,v| k[:qty] = v;k }.delete_if{|h| h[:qty].nil? and h[:unit].empty? }
# => [{:unit=>"oz", :type=>"mass", :qty=>5},
# {:unit=>"oz", :type=>"vol", :qty=>5},
# {:unit=>"lbs", :type=>"mass", :qty=>1},
# {:unit=>"o", :type=>"Foo", :qty=>nil}]