[英]Convert Ruby array of elements to Hash of counts with indices
給定Ruby中的二維數組:
[ [1, 1, 1],
[1, 1],
[1, 1, 1, 1],
[1, 1]
]
我想創建一個Hash,其中鍵是每個內部數組的計數,值是原始數組的索引數組,其內部數組大小具有特定計數。 由此產生的哈希將是:
{ 2 => [1, 3], 3 => [0], 4 => [2] }
我如何在Ruby中以簡潔的方式表達這一功能? 我正在嘗試類似於Hash.new([]).tap { |h| array.each_with_index { |a, i| h[a.length] << i } }
Hash.new([]).tap { |h| array.each_with_index { |a, i| h[a.length] << i } }
Hash.new([]).tap { |h| array.each_with_index { |a, i| h[a.length] << i } }
,但生成的Hash為空。
您的代碼有兩個問題。 第一個是當h
為空並且你寫,例如, h[2] << 1
,因為h
沒有鍵2
, h[2]
返回默認值,所以這個表達式變為[] << 1 #=> [1]
,但[1]
未附加到散列,因此不添加任何鍵和值。
你需要寫h[2] = h[2] << 1
1 。 如果你這樣做,你的代碼返回h #=> {3=>[0, 1, 2, 3], 2=>[0, 1, 2, 3], 4=>[0, 1, 2, 3]}
。 不幸的是,這仍然是不正確的,這將我們帶到您的代碼的第二個問題:您沒有正確定義新創建的哈希的默認值。
首先要注意的是
h[3].object_id
#=> 70113420279440
h[2].object_id
#=> 70113420279440
h[4].object_id
#=> 70113420279440
啊哈,這三個值都是同一個對象! 當h
沒有密鑰k
時, h[k]
返回new
的參數[]
。 的問題是,是相同的數組返回所有密鑰k
添加到哈希,所以你會增加一個鍵-值對為空數組的第一個新的密鑰,然后將第二鍵值對到該相同的下一個新鍵的數組,依此類推。 請參閱下文,了解如何定義哈希。
通過這兩個更改,您的代碼可以正常工作,但我建議您按如下方式編寫代碼。
arr = [ [1, 1, 1], [1, 1], [1, 1, 1, 1], [1, 1] ]
arr.each_with_index.with_object(Hash.new {|h,k| h[k]=[]}) { |(a,i),h|
h[a.size] << i }
#=> {3=>[0], 2=>[1, 3], 4=>[2]}
它使用Hash :: new的形式,它使用一個塊來計算哈希的默認值 (即當哈希h
沒有密鑰k
時由h[k]
返回的值),
要么
arr.each_with_index.with_object({}) { |(a,i),h| (h[a.size] ||= []) << i }
#=> {3=>[0], 2=>[1, 3], 4=>[2]}
這兩者實際上有以下幾點:
h = {}
arr.each_with_index do |a,i|
sz = a.size
h[sz] = [] unless h.key?(sz)
h[a.size] << i
end
h #=> {3=>[0], 2=>[1, 3], 4=>[2]}
另一種方法是在獲取每個內部數組的索引后,使用Enumerable#group_by ,對數組大小進行分組。
h = arr.each_with_index.group_by { |a,i| a.size }
#=> {3=>[[[1, 1, 1], 0]],
# 2=>[[[1, 1], 1], [[1, 1], 3]],
# 4=>[[[1, 1, 1, 1], 2]]}
h.each_key { |k| h[k] = h[k].map(&:last) }
#=> {3=>[0], 2=>[1, 3], 4=>[2]}
1表達式h[2] = h[2] << 1
使用方法Hash#[] =和Hash#[] ,這就是=
左邊的h[2]
不返回默認值的原因。 或者,該表達式可以寫成h[2] ||= [] << 1
。
arry = [ [1, 1, 1],
[1, 1],
[1, 1, 1, 1],
[1, 1]
]
h = {}
arry.each_with_index do |el,i|
c = el.count
h.has_key?(c) ? h[c] << i : h[c] = [i]
end
p h
這會給你
{3=>[0], 2=>[1, 3], 4=>[2]}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.