Ruby - 数组检查和替换

时间:2015-02-26 07:29:05

标签: javascript ruby arrays loops replace

假设:

check_for = ["Lorem", "ipsum", "dolor", "sit", "amet"]

replace_with = ["Donec", "ut", "libero", "sed", "arcu"]

sentence = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur."

如果它包含放在数组'check_for'中的单词并且如果找到它们,请如何检查'句子'中的整个字符串,替换为'replace_with'中的单词?

check_for中的单词可以替换为replace_with中具有相同索引的单词:

check_for [idx]应替换为replace_with [idx]

我使用嵌套循环使用Javascript做了类似的事情。出于某种原因,这不适用于Ruby。

我对嵌套循环的想法是将句子分成数组并使用带有i和j的while循环。因此,句子[i]将从0开始:

sentence[i] == check_for[j]

然后:

sentence[i] = replace_with[j]

除了这个想法不起作用之外,我确信在Ruby中还有一种更直接的方式。

不区分大小写即可。

2 个答案:

答案 0 :(得分:7)

可以使用定义替换的哈希来完成:

sentence = "Lorem ipsum dolor sit amet, consectetur adipiscing elit..."
replacements = {
  'Lorem' => 'Donec',
  'ipsum' => 'ut',
  'dolor' => 'libero',
  'sit'   => 'sed',
  'amet'  => 'arcu',
}

sentence.gsub(Regexp.union(replacements.keys), replacements)
#=> "Donec ut libero sed arcu, consectetur adipiscing elit..."

顺便说一下,您可以轻松地从数组中生成replacements哈希:

replacements = Hash[check_for.zip(replace_with)]

Cary Swoveland建议使用简化的Regexp:

sentence.gsub(/\w+/, replacements)

我真的很喜欢,因为它读得更好。

我想知道rexexp是否会对性能产生影响:一方面构建一个复杂但专门的正则表达式。另一方面,使用简单的正则表达式,但必须检查每个单词与哈希。

require 'benchmark'

def simple
  @sentence.gsub(/\w+/, @replacements)
end

def union
  @sentence.gsub(Regexp.union(@replacements.keys), @replacements)
end

n = 100_000
Benchmark.bmbm(15) do |x|
  x.report("simple :")   { n.times do; simple; end }
  x.report("union  :")   { n.times do; union ; end }
end

# Rehearsal ---------------------------------------------------
# simple :          4.790000   0.010000   4.800000 (  4.804576)
# union  :          3.820000   0.020000   3.840000 (  3.846012)
# ------------------------------------------ total: 8.640000sec

事实证明,较长的版本更快一点。但我很确定这可能会根据sentence的长度和要替换的元素数量而改变。

答案 1 :(得分:1)

使用#index method

,这是一种无需替换哈希的方法
replaced_sentence = []
sentence.split.each do |word|

  if idx = check_for.index(word.match(/\w+/).to_s) 
    replaced_sentence << word.gsub((/\w+/) , replace_with[idx] )
    else
     replaced_sentence << word
    end
 end

replaced_sentence.join(' ')
#=> "Donec ut libero sed amet, consectetur adipiscing elit..."

这会遍历句子的每个单词。如果check_for包含单词(减去标点符号),check_for.index(word...)将返回该索引值。然后将该索引值分配给idxreplace_with[idx]的值替换该单词,并且&#34;推送&#34;到新的replaced_sentence数组。

如果该字词不匹配,check_for.index(word)会返回nil,这会导致if语句不成立,原始word获得推到新阵列。