我如何计算红宝石字符串中唯一的多个单词



试图编写一个将计算唯一单词并返回其总出现的红宝石代码。

所以假设我想在以下一句话中找到萨利,玛丽娜和蒂娜的事件数量:"星期一蒂娜将与萨利和哈里斯见面。然后蒂娜将拜访她的妈妈玛丽娜。玛丽娜和蒂娜将见大卫吃晚饭。"

我尝试了以下内容,但这击败了干校长。有没有更好的办法?

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}

这将针对tmppeopole数组映射到包含[name, count]的嵌套数组,然后转换为哈希。

好处是,如果人们没有出现,它将返回0,请参阅'Dory'


为了获得总数,两种方法:

tmp.size #=> 8
counts.values.sum #=> 8

最新更新