试图编写一个将计算唯一单词并返回其总出现的红宝石代码。
所以假设我想在以下一句话中找到萨利,玛丽娜和蒂娜的事件数量:"星期一蒂娜将与萨利和哈里斯见面。然后蒂娜将拜访她的妈妈玛丽娜。玛丽娜和蒂娜将见大卫吃晚饭。"
我尝试了以下内容,但这击败了干校长。有没有更好的办法?
string = "Monday Tina will meet Sally and Harris. Then Tina will visit her mom Marina. Marina and Tina will meet David for dinner. Sally will then take Tina out for a late night party."
puts "Marina appears #{string.split.count("brown").to_i} times."
puts "Tina appears #{string.split.count("grey").to_i} times."
puts "Sally appears #{string.split.count("blue").to_i} times."
预期结果:程序通过文本查找独特的单词并返回它们。
实际:我必须用自己的puts lines and do string.split.count(对于那个唯一的单词)
将每个唯一单词用自己的puts line and do string.sning 进行硬编码。注意:我尝试了以下内容,但这给了我所有单词。我需要完善它,只给我我所要求的。这是我挣扎的地方。
def cw(string)
w = string.split(' ')
freq = Hash.new(0)
w.each { |w| freq[w.downcase] += 1 }
return freq
end
puts cw(string)
def count_em(str, who)
str.gsub(/b(?:#{who.join('|')})b/i).
each_with_object(Hash.new(0)) { |person,h| h[person] += 1 }
end
str = "Monday Tina will meet Sally and Harris. Then Tina will visit her " +
"mom Marina. Marina and Tina will meet David for dinner. Sally will " +
"then take Tina out for a late night party."
who = %w| Sally Marina Tina |
count_em(str, who)
#> {"Tina"=>4, "Sally"=>2, "Marina"=>2}
第一步如下。
r = /b(?:#{who.join('|')})b/i
#=> /b(?:Sally|Marina|Tina)b/i
enum = str.gsub(r)
#=> #<Enumerator: "Monday Tina will meet Sally and Harris. Then
# ...
# for a late night party.":gsub(/b(?:Sally|Marina|Tina)b/i)>
我们可以将其转换为数组,以查看将传递给each_with_object
的值。
enum.to_a
#=> ["Tina", "Sally", "Tina", "Marina", "Marina", "Tina", "Sally", "Tina"]
然后,我们简单地计算enum
生成的唯一值的实例数。
enum.each_with_object(Hash.new(0)) { |person,h| h[person] += 1 }
#=> {"Tina"=>4, "Sally"=>2, "Marina"=>2}
请参阅字符串#gsub,特别是当有一个参数而没有块时,请参见字符串#gsub。当然,这是对gsub
的不寻常使用,因为它没有替代,但是在这里我更喜欢String#scan
,因为gsub
返回枚举器,而扫描产生了临时数组。
另请参见hash :: new,new
采用参数而无块的情况。该参数称为默认值。如果h
是SOH SO-SONEDINES,则如果h
没有密钥k
,则h[k]
返回默认值。哈希没有改变。
此处默认值为零。当表达式h[person] += 1
解析时,它将转换为:
h[person] = h[person] + 1
如果person
等于"Tina"
,并且它是"Tina"
首次由枚举器生成并传递到块,则h
将没有键"Tina"
,因此表达式变为:
h["Tina"] = 0 + 1
作为 0
是默认值。下次"Tina"
传递给块,哈希具有密钥"Tina"
(带有值1
),因此执行以下计算。
h["Tina"] = h["Tina"] + 1 #=> 1 + 1 #=> 2
仅获取所需的人名称:
people = ['Marina', 'Tina', 'Sally', 'Dory']
tmp = string.scan(/w+/).keep_if{ |w| people.include? w }
counts people.map{ |name| [name, tmp.count{|n| n == name }] }.to_h
counts #=> {"Marina"=>2, "Tina"=>4, "Sally"=>2, "Dory"=>0}
这将针对tmp
的peopole
数组映射到包含[name, count]
的嵌套数组,然后转换为哈希。
好处是,如果人们没有出现,它将返回0
,请参阅'Dory'
。
为了获得总数,两种方法:
tmp.size #=> 8
counts.values.sum #=> 8