Arrays 如何按相同的元素对数组进行分组?
我有一个包含以下元素的数组:Arrays 如何按相同的元素对数组进行分组?,arrays,ruby,Arrays,Ruby,我有一个包含以下元素的数组: 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元素 键(:一个,:两个,:三个,:无)可以进行硬编码。您可以通过以下方式设置数组(元素): 之后,您可以使用“重命名”键: keys = { 1 => :on
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
元素
键(:一个
,:两个
,:三个
,:无
)可以进行硬编码。您可以通过以下方式设置数组(元素):
之后,您可以使用“重命名”键:
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]}
可以通过以下方式创建阵列(元素):
之后,您可以使用“重命名”键:
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]}
这个怎么样
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
这个怎么样
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
来自Perl的背景,我习惯于使用模糊的方法来使用数组和散列。这就是它对我的伤害: 使用
group\u 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]}
使用散列是从一件事映射到另一件事的简单方法:
new_keys = {
1 => :one,
2 => :two,
3 => :three,
nil => :none
}
以下是Perl影响我思维的地方:
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]}
因为他们都做同样的事情,但方式不同,我想知道什么是最快的。而且,因为我喜欢@Stefan的map
方法,我想看看特定方法在速度方面是否有任何优势:
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
Fruity没有发现任何显著的速度差异,背景任务影响了发现一致性差异的能力,所以我进行了五次比较。结果的顺序暗示了细微的差异,但其中任何一个看起来都是一个好办法:
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is faster than _zip by 19.999999999999996% ± 10.0%
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is similar to _zip
# >> _zip is similar to _map
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _inject is similar to _each_with_object
# >> _each_with_object is similar to _zip
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is faster than _zip by 19.999999999999996% ± 10.0%
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is faster than _zip by 19.999999999999996% ± 10.0%
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
来自Perl的背景,我习惯于使用模糊的方法来使用数组和散列。这就是它对我的伤害: 使用
group\u 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]}
使用散列是从一件事映射到另一件事的简单方法:
new_keys = {
1 => :one,
2 => :two,
3 => :three,
nil => :none
}
以下是Perl影响我思维的地方:
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]}
因为他们都做同样的事情,但方式不同,我想知道什么是最快的。而且,因为我喜欢@Stefan的map
方法,我想看看特定方法在速度方面是否有任何优势:
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
Fruity没有发现任何显著的速度差异,背景任务影响了发现一致性差异的能力,所以我进行了五次比较。结果的顺序暗示了细微的差异,但其中任何一个看起来都是一个好办法:
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is faster than _zip by 19.999999999999996% ± 10.0%
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is similar to _zip
# >> _zip is similar to _map
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _inject is similar to _each_with_object
# >> _each_with_object is similar to _zip
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is faster than _zip by 19.999999999999996% ± 10.0%
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
# >> Running each test 2048 times. Test will take about 1 second.
# >> _each_with_object is similar to _inject
# >> _inject is faster than _zip by 19.999999999999996% ± 10.0%
# >> _zip is faster than _map by 10.000000000000009% ± 10.0%
# >>
使用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]}
使用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]}
为什么需要这种奇怪且冗余的数据结构?如果你有每个元素的计数不是更好吗?像这样:
{1=>2,2=>1,3=>3,nil=>1}
你的问题是什么?钥匙的逻辑是什么?决定数组中元素数量的逻辑是什么?@sawa这是生成这样的散列的要求。有什么理由否决这个问题吗?我已经更新了这个问题。实际上,这个数组只能包含1、2、3和nil值。因此,这些键背后没有逻辑。密钥可以硬编码。为什么需要这种奇怪的冗余数据结构?如果你有每个元素的计数不是更好吗?像这样:{1=>2,2=>1,3=>3,nil=>1}
你的问题是什么?钥匙的逻辑是什么?决定数组中元素数量的逻辑是什么?@sawa这是生成这样的散列的要求。有什么理由否决这个问题吗?我已经更新了这个问题。实际上,这个数组只能包含1、2、3和nil值。因此,这些键背后没有逻辑。密钥可以硬编码。对于本身
ruby 2.2+是必需的,它不适用于旧版本。1+代表本身
我使用的是2.1.6。因此,我得到了1的未定义方法“自身”:Fixnum@Arif只需使用group_by{e|e}
case@Stefan谢谢,这正是我想要的。对于本身
ruby 2.2+是必需的,它不适用于旧版本。1+代表本身
我使用的是2.1.6。因此,我得到了1的未定义方法“自身”:Fixnum@Arif只需使用group_by{e|e}
case@Stefan谢谢,正是我想要的。