使用Reduce修改Ruby中字符串中的某些单词

时间:2019-02-20 17:50:48

标签: ruby functional-programming

keywords = ["fish", "blue"]
phrase = 'one fish two fish red fish blue fish'
actual = ???

assert_equal 'one FISH two FISH red FISH BLUE FISH', actual

简而言之,使用reduce,我应该替换什么???以上。

长期以来,有没有一种方法可以使用reduce来修改字符串中满足条件的每个单词。在这种情况下,我想upcase中包含的word中的每个phrase。我想我可以使用此方法,并进行一些修改,以删除或替换单词的每个实例。我了解keywordssub,但是我正在做一个问题集,使我相信使用reduce可以实现这一点。我去过无济于事的文档。

我只对使用reduce的解决方案感兴趣,或对为什么reduce在这种情况下不起作用的解释。

我可以使用它了。

gsub

Garret的评论将我引向正确的方向。我可能还不清楚,起初我只是不想在actual = keywords.reduce('one fish two fish red fish blue fish'){|memo,word| memo.gsub(word,word.upcase) } 之外的gsub解决方案。感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

如果使用reduce,我想您可以先在空格内分割字符串(如果将其标准化为始终由一个空格分隔),然后检查块中的当前单词是否在关键字数组中,如果是,将其推到备忘录的大写版本中,并在右侧添加一个空格,否则只需添加单词(加上空格):

new_phrase = phrase.split.reduce('') do |memo, word|
  pushed_word = if keywords.include?(word)
                  word.upcase
                else
                  word
                end
  memo << "#{pushed_word} "
end

p new_phrase
# "one FISH two FISH red FISH BLUE FISH "

当您再添加一个正确的空格时,可以使用rstrip来消除它。

答案 1 :(得分:0)

tl; dr

f1 = def upcase_fish(str); str.gsub('fish', 'FISH'); end
f2 = def upcase_blue(str); str.gsub('blue', 'BLUE'); end
[f1, f2].reduce(phrase){ |str, f| Method.send f, str }

说明

调用一个函数,使一个函数的输出成为下一函数的输入,是一种常见的用例。例如。这里我们有两个功能:一个大写“鱼”,另一个大写“蓝色”。当然,我们还可以添加其他转换,例如删除结尾的空格,大写首字母等。在函数式编程中,这可以通过减少函数的集合来实现。我们首先使用原始的phrase初始化结果,然后应用f1和f2。这等效于: f2(f1(phrase))

答案 2 :(得分:0)

有几种方法可以做到这一点。两者都旨在提高效率,并共享方法String#gsub和正则表达式:

r = /\p{Alpha}+/

这匹配一个或多个Unicode字母。

keywords = ["fish", "blue"]
phrase = "one fish two Fish red fisH blue fish."

请注意,在我将第一个“ Fish”大写时,将第二个“ FisH”中的“ H”大写并添加了句号。

使用String#gsub的形式,该形式采用哈希进行替换

subs = keywords.each_with_object({}) { |word,h|
  h[word] = word.capitalize }
  #=> {"fish"=>"Fish", "blue"=>"Blue"} 
subs.default_proc = Proc.new { |_,word|
  subs.include?(word.downcase) ? word.upcase : word } 
  #=> #<Proc:0x000059dc26dd1510@(irb):95> 
phrase.gsub(r, subs)
  #=> "one Fish two FISH red FISH Blue Fish." 

如果word不是subs的键,则默认proc返回一个字符串。如果word.downcasesubs的键,则返回word.upcase;否则word保持不变。参见Hash#default_proc=

使用设置来加快查找速度

require 'set'

subs = keywords.to_set
  #=> #<Set: {"fish", "blue"}> 
phrase.gsub(r) { |word|
  subs.include?(word.downcase) ? word.upcase : word }
  #=> "one FISH two FISH red FISH BLUE FISH."