我有以下陣列:
arr1 = [1, 2, 3, 4]
arr2 = [a, b, a, c]
我想要以下輸出:
out = {'a' => [1, 3], 'b'=> [2], 'c' => [4]}
在 Ruby 中是否有一種簡便的方法可以做到這一點?目前,我正在使用回圈和索引來創建哈希。
uj5u.com熱心網友回復:
您可以撰寫以下內容。
arr1 = [1, 2, 3, 4]
arr2 = ['a', 'b', 'a', 'c']
arr1.zip(arr2).each_with_object(Hash.new { |h,k| h[k] = [] }) do |(n,c),h|
h[c] << n
end
#=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}
讓我從一個簡單的程序方法開始解釋這個運算式,然后通過幾個步驟來改進代碼。
首先創建一個空散列,它將成為您想要的回傳值:
h = {}
然后我們可以寫如下
(0..arr1.size - 1).each do |i|
n = arr1[i]
c = arr2[i]
h[c] = [] unless h.key?(c)
h[c] << n
end
h #=>{"a"=>[1, 3], "b"=>[2], "c"=>[4]}
它更像 Ruby,但是迭代來自arr1and 的相應值對arr2,即,[1, 'a'],[2, 'b'],等等。為此,我們使用方法Array#zip:
pairs = arr1.zip(arr2)
#=> [[1, "a"], [2, "b"], [3, "a"], [4, "c"]]
然后
h = {}
pairs.each do |pair|
n = pair.first
c = pair.last
h[c] = [] unless h.key?(c)
h[c] << n
end
h #=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}
我們可以做的一個小改進是將陣列分解應用于pair:
h = {}
pairs.each do |n,c|
h[c] = [] unless h.key?(c)
h[c] << n
end
h #=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}
下一個改進是替換each為Enumerable#each_with_object以避免h = {}在開始和h結束時需要:
pairs.each_with_object({}) do |(n,c),h|
h[c] = [] unless h.key?(c)
h[c] << n
end
#=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}
Notice how I have written the block variables, with h holding the object that is returned (an initially-empty hash). This is another use of array decomposition. For more on that subject, see this article.
The previous expression is fine, and reads well, but the following tweak is often seen:
pairs.each_with_object({}) do |(n,c),h|
(h[c] ||= []) << n
end
#=> {"a"=>[1, 3], "b"=>[2], "c"=>[4]}
If h does not have a key c, h[c] returns nil, so h[c] ||= [], or h[c] = h[c] || [], becomes h[c] = nil || [], ergo h[c] = [], after which h[c] << n is executed.
No better or worse than the previous expression, you may see also see the code I presented at the beginning:
arr1.zip(arr2).each_with_object(Hash.new { |h,k| h[k] = [] }) do |(n,c),h|
h[c] << n
end
Here the block variable h is initialized to an empty hash defined
h = Hash.new { |h,k| h[k] = [] }
這采用了Hash::new的形式,它接受一個塊而沒有引數。當哈希h以這種方式被定義,如果h沒有一個鍵c,執行h[c]原因h[c] = []之前執行h[c] << n被執行。
uj5u.com熱心網友回復:
假設你的意思是
arr1 = [1, 2, 3, 4]
arr2 = %w[a b a c] # ["a", "b", "a", "d"]
所以你的第二個陣列是一個字串陣列而不是變數
您可以使用group_by和each_with_index列舉器指向您的變數索引并使用第二個陣列對其進行分組
arr1.group_by.each_with_index { |_, index| arr2[index] }
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/358169.html
上一篇:如何在組中計算特定值?
