假设我有一个字符串"I am a good boy".我想要字符串中每个字母的总数.字母区分大小写.也就是说,D和d需要被视为两个不同的字符.
saw*_*awa 19
"I am a good boy".scan(/\w/).inject(Hash.new(0)){|h, c| h[c] += 1; h}
# => {"I"=>1, "a"=>2, "m"=>1, "g"=>1, "o"=>3, "d"=>1, "b"=>1, "y"=>1}
Run Code Online (Sandbox Code Playgroud)
Dig*_*oss 14
a = "I am a good boy"
a.chars.group_by(&:chr).map { |k, v| [k, v.size] }
Run Code Online (Sandbox Code Playgroud)
这不是一个答案,只是对现有答案的补充.
因为讨论了性能,所以这里有一些数据.
require 'benchmark'
s0 = "I am a good boy"
s = s0 * 1
N = 10000
Benchmark.bm(20) do | x |
x.report('sawa') do
N.times { s.scan(/\w/).inject(Hash.new(0)){|h, c| h[c] += 1; h} }
end
x.report('digitalross') do
N.times { s.chars.to_a.sort.group_by(&:chr).map { |k, v| [k, v.size] } }
end
x.report("digitalross'") do
N.times { s.chars.group_by(&:chr).map { |k, v| [k, v.size] } }
end
x.report('rubylovely') do
N.times { s.gsub(/\s/,'').chars.with_object({}) {|c,ob| ob[c] = s.count(c)} }
end
end
Run Code Online (Sandbox Code Playgroud)
给(ruby 1.9.3p392在我的机器上)
user system total real
sawa 0.600000 0.000000 0.600000 ( 0.601734)
digitalross 0.790000 0.000000 0.790000 ( 0.806674)
digitalross' 0.640000 0.010000 0.650000 ( 0.651802)
rubylovely 0.570000 0.000000 0.570000 ( 0.572501)
Run Code Online (Sandbox Code Playgroud)
有了s = s0 * 1000,N = 10我得到了
user system total real
sawa 0.340000 0.000000 0.340000 ( 0.340617)
digitalross 0.380000 0.000000 0.380000 ( 0.411393)
digitalross' 0.230000 0.010000 0.240000 ( 0.243389)
rubylovely 6.530000 0.000000 6.530000 ( 6.603198)
Run Code Online (Sandbox Code Playgroud)
所以对于非常短的字符串,RubyLovely解决方案的多次计数并没有受到伤害.实际上,它确实如此.
我用的是:
str = "I am a good boy"
str.scan(/[[:alpha:]]/i).each_with_object(Hash.new(0)) { |c, h| h[c] += 1 }
哪个回报:
{
"I" => 1,
"a" => 2,
"m" => 1,
"g" => 1,
"o" => 3,
"d" => 1,
"b" => 1,
"y" => 1
}
我更喜欢使用,scan因为它使用的正则表达式立即确定允许计算哪些字符.如果输入的字符串包含"我是个好孩子".其他一些解决方案会失败,因为它们对输入字符串太具体,并且每次遇到意外字符时都需要调整.我们知道输入很少是无效的,在现实世界中,这种代码将被用于一般句子.预先忽略不需要的角色很重要.
'Français'.scan(/[[:alpha:]]/i).each_with_object(Hash.new(0)) { |c, h| h[c] += 1 }
哪个回报:
{
"F" => 1,
"r" => 1,
"a" => 2,
"n" => 1,
"ç" => 1,
"i" => 1,
"s" => 1
}