2

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'}
]

:qtynilであり: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 を付けるべきではありません。

4

3 に答える 3

8

group_by必要なキーを使用して開始し、各値reduceqtys を単一のハッシュにするか、代わりにnilif they are allを使用し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}]

properties2 番目のサンプル入力データはどこにありますか。

于 2013-08-24T18:09:23.113 に答える
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"}
  ]
}
于 2013-08-24T18:06:28.623 に答える
-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}]

@Andrew Marshallを検討中

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}]
于 2013-08-24T18:10:39.693 に答える