如何计算Ruby字符串中唯一的多个单词?

如何计算Ruby字符串中唯一的多个单词?,ruby,string,block,Ruby,String,Block,尝试编写一个Ruby代码来计算唯一的单词并返回它们的总出现次数 因此,假设我想在下面的句子中找到Sally、Marina和Tina的出现次数“周一Tina将会见Sally和Harris,然后Tina将拜访她的母亲Marina。Marina和Tina将与David共进晚餐。” 我试过下面的方法,但失败了。有更好的办法吗 string = "Monday Tina will meet Sally and Harris. Then Tina will visit her mom Marina. Mar

尝试编写一个Ruby代码来计算唯一的单词并返回它们的总出现次数

因此,假设我想在下面的句子中找到Sally、Marina和Tina的出现次数“周一Tina将会见Sally和Harris,然后Tina将拜访她的母亲Marina。Marina和Tina将与David共进晚餐。”

我试过下面的方法,但失败了。有更好的办法吗

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行上硬编码,并执行string.split.count(针对该唯一的单词)

注: 我试过下面的方法,但这给了我每一个字。我需要改进它,以满足我的需求。这就是我努力奋斗的地方

def cw(string)
  w = string.split(' ')
  freq = Hash.new(0)
  w.each { |w| freq[w.downcase] += 1 }
  return freq
end
puts cw(string)

要仅获取所需的人员姓名,请执行以下操作:

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}
这将
peopole
数组与
tmp
映射到包含
[name,count]
的嵌套数组,然后转换为哈希

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

要获取总计数,有两种方法:

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

要仅获取所需的人员姓名,请执行以下操作:

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}
这将
peopole
数组与
tmp
映射到包含
[name,count]
的嵌套数组,然后转换为哈希

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

要获取总计数,有两种方法:

tmp.size #=> 8
counts.values.sum #=> 8
第一步如下

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)>
然后,我们只需计算由
enum
生成的唯一值的实例数

enum.each_with_object(Hash.new(0)) { |person,h| h[person] += 1 }
  #=> {"Tina"=>4, "Sally"=>2, "Marina"=>2}
请参阅,特别是在只有一个参数且没有块的情况下。这无疑是
gsub
的一个不寻常的用法,因为它不进行替换,但在这里我更喜欢它而不是
String#scan
,因为
gsub
返回一个枚举数,而scan生成一个临时数组

另请参见
new
接受参数且不带块的情况。该参数称为默认值。如果
h
是这样定义的散列,则默认值由
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
第一步如下

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)>
然后,我们只需计算由
enum
生成的唯一值的实例数

enum.each_with_object(Hash.new(0)) { |person,h| h[person] += 1 }
  #=> {"Tina"=>4, "Sally"=>2, "Marina"=>2}
请参阅,特别是在只有一个参数且没有块的情况下。这无疑是
gsub
的一个不寻常的用法,因为它不进行替换,但在这里我更喜欢它而不是
String#scan
,因为
gsub
返回一个枚举数,而scan生成一个临时数组

另请参见
new
接受参数且不带块的情况。该参数称为默认值。如果
h
是这样定义的散列,则默认值由
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

我能够做到这一点,但随后不得不手动返回或打印每个关键字(在本例中,我只查找三个唯一的单词出现的次数)。我已经能够得到我的函数来显示所有事件;我希望它只显示我正在寻找的三个词。您正在滥用
每次迭代来执行缩减
string.scan(/\w++/).map(&:downcase)。每个_与_对象(Hash.new(0)){w,h | h[w]+=1}
@AlekseiMatiushkin,是的,我只是想分割步骤,只是为了让它更容易遵循。当然,
每个带有对象的对象都非常方便。@iGian,我怎么把它们合计起来呢?所以最后一行将显示8个出现的名称。我能够做到这一点,但必须手动返回或打印每个关键字(在本例中,我只查找三个唯一的单词出现的次数)。我已经能够得到我的函数来显示所有事件;我希望它只显示我正在寻找的三个词。您正在滥用
每次迭代来执行缩减
string.scan(/\w++/).map(&:downcase)。每个_与_对象(Hash.new(0)){w,h | h[w]+=1}
@AlekseiMatiushkin,是的,我只是想分割步骤,只是为了让它更容易遵循。当然,
每个带有对象的对象都非常方便。@iGian,我怎么把它们合计起来呢?所以最后一行将显示8个出现的名称。
scan
在语义上是否比
gsub
?:)更正确mudsie,er@AlekseiMatiushkin,我更喜欢
gsub
而不是
scan
,因为前者生成一个枚举器,而后者则构造一个中间数组。此外,重要的是要教育人们当使用一个参数而不使用阻塞时,
gsub
的有用性。@Rajagopalan,游戏?不是打架