ruby 数组到哈希:字数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9480852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Array to Hash : words count
提问by demas
I have array of words and I want to get a hash, where keys are words and values are word count.
我有一个单词数组,我想得到一个哈希值,其中键是单词,值是单词计数。
Is there any more beautiful way then my:
有没有比我的更漂亮的方式:
result = Hash.new(0)
words.each { |word| result[word] += 1 }
return result
回答by tokland
The imperative approach you used is probably the fastest implementation in Ruby. With a bit of refactoring, you can write a one-liner:
您使用的命令式方法可能是 Ruby 中最快的实现。通过一些重构,您可以编写一个单行代码:
wf = Hash.new(0).tap { |h| words.each { |word| h[word] += 1 } }
Another imperative approach using Enumerable#each_with_object:
另一种命令式方法使用Enumerable#each_with_object:
wf = words.each_with_object(Hash.new(0)) { |word, acc| acc[word] += 1 }
A functional/immutable approach using existing abstractions:
使用现有抽象的功能/不可变方法:
wf = words.group_by(&:itself).map { |w, ws| [w, ws.length] }.to_h
Note that this is still O(n)in time, but it traverses the collection three times and creates two intermediate objects along the way.
请注意,这在时间上仍然是O(n),但它遍历了集合 3 次,并在此过程中创建了两个中间对象。
Finally: a frequency counter/histogram is a common abstraction that you'll find in some libraries like Facets: Enumerable#frequency.
最后:频率计数器/直方图是一种常见的抽象,您可以在某些库中找到,例如 Facets: Enumerable#frequency。
require 'facets'
wf = words.frequency
回答by Baldrick
With inject:
与inject:
str = 'I have array of words and I want to get a hash, where keys are words'
result = str.split.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
=> {"I"=>2, "have"=>1, "array"=>1, "of"=>1, "words"=>2, "and"=>1, "want"=>1, "to"=>1, "get"=>1, "a"=>1, "hash,"=>1, "where"=>1, "keys"=>1, "are"=>1}
I don't know about the efficiency.
我不知道效率如何。
回答by Pawan
Posted on a related question, but posting here for visibility as well:
发布在相关问题上,但也发布在这里以提高知名度:
Ruby 2.7 onwards will have the Enumerable#tallymethod that will solve this.
Ruby 2.7 以后Enumerable#tally会有解决这个问题的方法。
From the trunk documentation:
从主干文档:
Tallys the collection. Returns a hash where the keys are the elements and the values are numbers of elements in the collection that correspond to the key.
统计集合。返回一个散列,其中键是元素,值是集合中与键对应的元素数。
["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
回答by Boris Lopez
irb(main):001:0> %w(foo bar foo bar).each_with_object(Hash.new(0)) { |w, m| m[w] += 1 }
=> {"foo"=>2, "bar"=>2}
as @mfilej said
正如@mfilej 所说

