我有一个包含以下元素的数组:
array = [1, 2, 1, 3, 2, nil, 3, 3]
我想通过匹配元素对它们进行分组并将其分配给哈希。输出应该如下所示:
{ one: [1, 1], two: [2, 2], three: [3, 3, 3], none: [nil] }
注意:array
只能包含1
,2
,3
和nil
元素。
密钥(:one
,:two
,:three
,:none
)可以进行硬编码。
答案 0 :(得分:6)
array = [1, 2, 1, 3, 2, nil, 3, 3]
hash = array.group_by(&:itself)
#=> {1=>[1, 1], 2=>[2, 2], 3=>[3, 3, 3], nil=>[nil]}
之后,您可以使用map
来重命名"钥匙:
keys = { 1 => :one, 2 => :two, 3 => :three, nil => :none }
hash.map { |k, v| [keys[k], v] }.to_h
#=> {:one=>[1, 1], :two=>[2, 2], :three=>[3, 3, 3], :none=>[nil]}
答案 1 :(得分:1)
来自Perl背景,我曾经习惯于模糊阵列和哈希的混淆方法。以下是它如何损害我:
使用window.location
是找到相似之处的明显方法:
group_by
使用哈希是从一件事物到另一件事物的简单方法:
array = [1, 2, 1, 3, 2, nil, 3, 3]
hash = array.group_by{ |i| i } # => {1=>[1, 1], 2=>[2, 2], 3=>[3, 3, 3], nil=>[nil]}
Perl影响力影响了我的想法:
new_keys = {
1 => :one,
2 => :two,
3 => :three,
nil => :none
}
因为他们都做同样的事情,但以不同的方式,我想知道什么是最快的。而且,因为我喜欢@ Stefan的new_keys.values.zip(hash.values_at(*new_keys.keys)).to_h # => {:one=>[1, 1], :two=>[2, 2], :three=>[3, 3, 3], :none=>[nil]}
new_keys.each_with_object({}){ |(k, v), h| h[v] = hash[k] } # => {:one=>[1, 1], :two=>[2, 2], :three=>[3, 3, 3], :none=>[nil]}
new_keys.inject({}){ |h, (k, v)| h[v] = hash[k]; h } # => {:one=>[1, 1], :two=>[2, 2], :three=>[3, 3, 3], :none=>[nil]}
方法,所以我想看看特定方法是否有任何速度优势:
map
Fruity无法找到任何显着的速度差异,而后台任务正在影响找到一致差异的能力,所以我进行了五次比较。根据结果的顺序暗示了微小的差异,但这些看起来都是一个很好的方法:
require 'fruity'
5.times do
compare do
_zip { new_keys.values.zip(hash.values_at(*new_keys.keys)).to_h }
_each_with_object { new_keys.each_with_object({}){ |(k, v), h| h[v] = hash[k] } }
_inject { new_keys.inject({}){ |h, (k, v)| h[v] = hash[k]; h } }
_map { hash.map { |k, v| [new_keys[k], v] }.to_h }
end
puts
end
答案 2 :(得分:1)
使用humanize gem将数字转换为单词的简短解决方案。
require 'humanize'
array.group_by { |e| e.humanize.to_sym rescue :none }
# => {:one=>[1, 1], :two=>[2, 2], :three=>[3, 3, 3], :none=>[nil]}
答案 3 :(得分:0)
这个怎么样
hash = array.group_by{|e| e}
[hash].each do |k|
k[:one] = k.delete 1
k[:two] = k.delete 2
k[:three] = k.delete 3
k[:none] = k.delete nil
end
你会得到你的输出。如果您不想循环执行以下操作
hash[:one] = hash.delete 1
hash[:two] = hash.delete 2
hash[:three] = hash.delete 3
hash[:none] = hash.delete nil