我有一个排序数组:
[ 'FATAL', 'FATAL ', 'FATAL ' ]
我想得到这样的东西,但它不一定是哈希:
[ {:error => 'FATAL', :count => 2}, {:error => 'FATAL ', :count => 1} ]
nimrodm.. 125
以下代码打印您要求的内容.我会让你决定如何实际用来生成你正在寻找的哈希:
# sample array a=["aa","bb","cc","bb","bb","cc"] # make the hash default to 0 so that += will work correctly b = Hash.new(0) # iterate over the array, counting duplicate entries a.each do |v| b[v] += 1 end b.each do |k, v| puts "#{k} appears #{v} times" end
注意:我刚注意到你说数组已经排序了.上面的代码不需要排序.使用该属性可能会产生更快的代码.
以下代码打印您要求的内容.我会让你决定如何实际用来生成你正在寻找的哈希:
# sample array a=["aa","bb","cc","bb","bb","cc"] # make the hash default to 0 so that += will work correctly b = Hash.new(0) # iterate over the array, counting duplicate entries a.each do |v| b[v] += 1 end b.each do |k, v| puts "#{k} appears #{v} times" end
注意:我刚注意到你说数组已经排序了.上面的代码不需要排序.使用该属性可能会产生更快的代码.
您可以使用以下方式非常简洁地(一行)执行此操作inject
:
a = ['FATAL', 'FATAL ', 'FATAL '] b = a.inject(Hash.new(0)) {|h,i| h[i] += 1; h } b.to_a.each {|error,count| puts "#{count}: #{error}" }
会产生:
1: FATAL2: FATAL
如果您有这样的数组:
words = ["aa","bb","cc","bb","bb","cc"]
在需要计算重复元素的地方,一行解决方案是:
result = words.each_with_object(Hash.new(0)) { |word,counts| counts[word] += 1 }
使用Enumerable#group_by对上述答案采用不同的方法.
[1, 2, 2, 3, 3, 3, 4].group_by(&:itself).map { |k,v| [k, v.count] }.to_h # {1=>1, 2=>2, 3=>3, 4=>1}
将其分解为不同的方法调用:
a = [1, 2, 2, 3, 3, 3, 4] a = a.group_by(&:itself) # {1=>[1], 2=>[2, 2], 3=>[3, 3, 3], 4=>[4]} a = a.map { |k,v| [k, v.count] } # [[1, 1], [2, 2], [3, 3], [4, 1]] a = a.to_h # {1=>1, 2=>2, 3=>3, 4=>1}
Enumerable#group_by
在Ruby 1.8.7中添加了.
以下内容如何:
things = [1, 2, 2, 3, 3, 3, 4] things.uniq.map{|t| [t,things.count(t)]}.to_h
它有点干净,更能描述我们真正想要做的事情.
我怀疑它在大型集合中的表现也会比迭代每个值的表现更好.
基准性能测试:
a = (1...1000000).map { rand(100)} user system total real inject 7.670000 0.010000 7.680000 ( 7.985289) array count 0.040000 0.000000 0.040000 ( 0.036650) each_with_object 0.210000 0.000000 0.210000 ( 0.214731) group_by 0.220000 0.000000 0.220000 ( 0.218581)
所以速度要快得多.
就个人而言,我会这样做:
# myprogram.rb a = ['FATAL', 'FATAL ', 'FATAL '] puts a
然后运行程序并将其传递给uniq -c:
ruby myprogram.rb | uniq -c
输出:
2 FATAL1 FATAL
从Ruby> = 2.2开始,您可以使用itself
:array.group_by(&:itself).transform_values(&:count)
详细介绍:
array = [ 'FATAL', 'FATAL ', 'FATAL ' ]; array.group_by(&:itself).transform_values(&:count) => { "FATAL "=>2, "FATAL "=>1 }