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
。我想我可以使用此方法,并进行一些修改,以删除或替换单词的每个实例。我了解keywords
和sub
,但是我正在做一个问题集,使我相信使用reduce可以实现这一点。我去过无济于事的文档。
我只对使用reduce的解决方案感兴趣,或对为什么reduce在这种情况下不起作用的解释。
我可以使用它了。
gsub
Garret的评论将我引向正确的方向。我可能还不清楚,起初我只是不想在actual = keywords.reduce('one fish two fish red fish blue fish'){|memo,word| memo.gsub(word,word.upcase) }
之外的gsub
解决方案。感谢您的帮助!
答案 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.downcase
是subs
的键,则返回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."