結合我有散列的這樣一個數組:如何將多個散列值的數組中有相同鍵
[{"apple"=>5}, {"banana"=>4}, {"orange"=>6}, {"apple"=>4}, {"orange"=>2}]
我如何到達:
[{"apple"=>9}, {"banana"=>4}, {"orange"=>8}]
結合我有散列的這樣一個數組:如何將多個散列值的數組中有相同鍵
[{"apple"=>5}, {"banana"=>4}, {"orange"=>6}, {"apple"=>4}, {"orange"=>2}]
我如何到達:
[{"apple"=>9}, {"banana"=>4}, {"orange"=>8}]
還有:
cache = Hash.new { |h, k| h[k] = { k => 0 } }
aoh.flat_map(&:to_a)
.each_with_object(cache) { |(k,v),h| h[k][k] += v }
.values
或者更多條要更清晰一點:
cache = Hash.new { |h, k| h[k] = { k => 0 } }
sum = -> ((k, v), h) { h[k][k] += v }
summary = aoh.flat_map(&:to_a)
.each_with_object(cache, &sum)
.values
的有些奇怪的看着cache
哈希沒有馬上兩件事情:
這很可愛....... – 2015-04-03 23:32:06
@CarySwoveland謝謝。在「現實生活」中,我可能會使用包裝在一個很好命名的方法中的「更多部分」版本。我非常喜歡「使用lambda而不是塊,以便它可以有名稱」技巧。 – 2015-04-04 00:14:29
我注意到了。 「......在他的腦海中,他有一個lambda,EIEIO,在這裏有一個'call''''',''''''''','''這裏有一個'()', ',到處都是'電話號碼','電話號碼...... – 2015-04-04 01:26:52
有許多方式,你會很快看到。這裏有一個:
arr = [{"apple"=>5}, {"banana"=>4}, {"orange"=>6}, {"apple"=>4}, {"orange"=>2}]
arr.flat_map(&:to_a)
.group_by(&:first)
.map { |k,a| { k=>(a.reduce(0) { |tot,(_,v)| tot+v }) } }
#=> [{"apple"=>9}, {"banana"=>4}, {"orange"=>8}]
步驟:
a = arr.flat_map(&:to_a)
#=> [["apple",5], ["banana",4], ["orange",6], ["apple",4], ["orange",2]]
b = a.group_by(&:first)
#=> {"apple"=>[["apple", 5], ["apple", 4]],
# "banana"=>[["banana", 4]],
# "orange"=>[["orange", 6], ["orange", 2]]}
b.map { |k,a| { k=>(a.reduce(0) { |tot,(_,v)| tot+v }) } }
#=> [{"apple"=>9}, {"banana"=>4}, {"orange"=>8}]
讓我們來仔細看看b.map
:
enum = b.map
#=> #<Enumerator: {
# "apple"=>[["apple", 5], ["apple", 4]],
# "banana"=>[["banana", 4]],
# "orange"=>[["orange", 6], ["orange", 2]]
# }:map>
的enum
第一個元素傳遞(通過Enumerator#each,進而調用Array#each)添加到塊並分配給塊變量。我們可以模擬,使用Enumerator#next:
k,a = enum.next
#=> ["apple", [["apple", 5], ["apple", 4]]]
k #=> "apple"
a #=> [["apple", 5], ["apple", 4]]
要計算:
c = a.reduce(0) { |tot,(_,v)| tot+v }
#=> 9
的a
第一元件被傳遞到塊和塊變量被分配:
tot, (_,v) = 0, ["apple", 5]
#=> [0, ["apple", 5]]
tot #=> 0
v #=> 5
我們然後計算:
tot + 5
#=> 0+5 => 5
返回reduce
成爲更新值tot
。的a
第二值是在通過:
tot, (_,v) = 5, ["apple", 4]
tot #=> 5
v #=> 4
,我們計算和返回:
tot+4
# 5+4 => 9
這樣:
{ k=>tot }
#=> { "apple"=>9 }
是a
所述第一元件的所映射的值。其餘映射值的計算方法相似。
向我們展示您到目前爲止所擁有的。 – fuesika 2015-04-04 01:15:12