代碼和例如
[arr.each_with_object(Hash.new(0)) { |pair, h| h[pair] += 1 }.
each_with_object(Hash.new { |h,k| h[k]=[] }) { |((a,b),n),g| g[a] << [b,n] }]
#=> [{"IT"=>[["Testing", 3], ["Banking Software", 1], ["ERP", 2], ["IT Security", 2]],
# "Accounting"=>[["Offshore", 1], ["ACCA", 1]]}]
爲什麼含有單個散列(而不僅僅是散列)的陣列所需的目前尚不清楚。如果散列是所有需要的,只需刪除代碼中的外括號即可。
說明
Hash.new(0)
有時被稱爲計數散列。 (請參閱Hash::new。)如果h = Hash.new(0)
和h
沒有密鑰:cat
,則h[:cat]
將返回默認值(此處爲零),而不更改散列。當紅寶石遇到h[:cat] += 1
,它做的第一件事就是展開表達:
h[:cat] = h[:cat] + 1
如果h
有一個關鍵:cat
,h[:cat]
在平等的右側是該鍵的當前值,說8
。然後我們計算
h[:cat] = 8 + 1 #=> 9
在另一方面,如果h
沒有一個關鍵:cat
,h[:cat]
右側被設置爲默認值,所以我們必須
h[:cat] = 0 + 1 #=> 0
因此,在第一步驟中,我們計算散列如下:
g = arr.each_with_object(Hash.new(0)) { |pair, h| h[pair] += 1 }
#=> {["IT", "Testing"]=>3, ["IT", "Banking Software"]=>1, ["IT", "ERP"]=>2,
# ["IT", "IT Security"]=>2, ["Accounting", "Offshore"]=>1, ["Accounting", "ACCA"]=>1}
這是幾乎一樣的簡單的形式
h = {}
arr.each do |pair|
h[pair] = 0 unless h.key?(pair)
h[pair] += 1
end
#=> [["IT", "Testing"], ["IT", "Banking Software"], ["IT", "ERP"],
# ["IT", "Testing"], ["IT", "IT Security"], ["IT", "ERP"],
# ["IT", "IT Security"], ["Accounting", "Offshore"], ["IT", "Testing"],
# ["Accounting", "ACCA"]]
h #=> {["IT", "Testing"]=>3, ["IT", "Banking Software"]=>1, ["IT", "ERP"]=>2,
# ["IT", "IT Security"]=>2,
# ["Accounting", "Offshore"]=>1, ["Accounting", "ACCA"]=>1}
請注意,each
返回它的接收器,所以如果此代碼段被封裝在一個方法中,我們需要結束行h
。
第二步(使用剛剛計算的h
)實現了以下功能。
g = {}
h.each do |k,n|
a, b = k
g[a] = [] unless g.key?(a)
g[a] << [b, n]
end
g # => {"IT"=>[["Testing", 3], ["Banking Software", 1], ["ERP", 2], ["IT Security", 2]],
# "Accounting"=>[["Offshore", 1], ["ACCA", 1]]}
1注意,h[k] =
是用於該方法Hash#[]=語法糖,而h[k]
上平等的右邊是方法Hash#[]。
你是什麼意思「沒有成功」呢?它沒有工作嗎?它給你無效的輸出嗎? – Makoto
作爲寫的,這是一個問題,「我寫的代碼」。我想幫你過去,你就完蛋了,但除非你分享的細節,我也沒有辦法。 –