ルビーに変換したい
[[1, 1], [2, 3], [3, 5], [4, 1], [1, 2], [2, 3], [3, 5], [4, 1]]
の中へ
[{1=>1}, {2=>3}, {3=>5}, {4=>1}, {1=>2}, {2=>3}, {3=>5}, {4=>1}]
この後、すべての異なるキーの合計を取得します。
{1=>3,2=>6,3=>10,4=>2}
ルビーに変換したい
[[1, 1], [2, 3], [3, 5], [4, 1], [1, 2], [2, 3], [3, 5], [4, 1]]
の中へ
[{1=>1}, {2=>3}, {3=>5}, {4=>1}, {1=>2}, {2=>3}, {3=>5}, {4=>1}]
この後、すべての異なるキーの合計を取得します。
{1=>3,2=>6,3=>10,4=>2}
機能的アプローチ:
xs = [[1, 1], [2, 3], [3, 5], [4, 1], [1, 2], [2, 3], [3, 5], [4, 1]]
Hash[xs.group_by(&:first).map do |k, pairs|
[k, pairs.map { |x, y| y }.inject(:+)]
end]
#=> {1=>3, 2=>6, 3=>10, 4=>2}
抽象化(のバリエーション)と(+ )のおかげで、ファセットの使用ははるかに簡単です。map_by
group_by
mash
map
Hash
require 'facets'
xs.map_by { |k, v| [k, v] }.mash { |k, vs| [k, vs.inject(:+)] }
#=> {1=>3, 2=>6, 3=>10, 4=>2}
2番目の質問について
sum = Hash.new(0)
original_array.each{|x, y| sum[x] += y}
sum # => {1 => 3, 2 => 6, 3 => 10, 4 => 2}
中間形式は必要ありません。
arrays = [[1, 1], [2, 3], [3, 5], [4, 1], [1, 2], [2, 3], [3, 5], [4, 1]]
aggregate = arrays.each_with_object Hash.new do |(key, value), hash|
hash[key] = hash.fetch(key, 0) + value
end
aggregate # => {1=>3, 2=>6, 3=>10, 4=>2}
arr= [[1, 1], [2, 3], [3, 5], [4, 1], [1, 2], [2, 3], [3, 5], [4, 1]]
final = Hash.new(0)
second_step = arr.inject([]) do |arr,inner|
arr << Hash[*inner]
final[inner.first] += inner.last
arr
end
second_step
#=> [{1=>1}, {2=>3}, {3=>5}, {4=>1}, {1=>2}, {2=>3}, {3=>5}, {4=>1}]
final
#=> {1=>3, 2=>6, 3=>10, 4=>2}
最後のステップのみが直接必要な場合
arr.inject(Hash.new(0)){|hash,inner| hash[inner.first] += inner.last;hash}
=> {1=>3, 2=>6, 3=>10, 4=>2}