如何停止覆盖推入数组的先前字符串?

时间:2018-04-12 18:04:59

标签: ruby

我试图推动句子的所有推导。

例如:The < animal > in the < object >

我希望派系能够保留扩展,因此derivation[0]会有"The cat in the < object >",而derivation[1]会有"The cat in the hat"

然而,在被最终推导覆盖之前的所有推导。

如何防止这种情况发生?

while is_non_terminal?(sentence)
 $key = sentence.match(/(\<[a-zA-Z0-9_\-*]+\>)/)
 sentence.sub!(/(\<[a-zA-Z0-9_\-*]+\>)/){grammar[$key.to_s].sample.join(' ')}
 derivations.push(sentence)
 puts derivations.to_s
 #puts sentence
end

2 个答案:

答案 0 :(得分:2)

您的代码中只有一个字符串,并且您不断修改它并将新引用推送到数组中。数组中的每个条目只是对相同字符串的引用。

您应该使用sub而不是sub!来返回您可以推送到数组中的字符串的修改副本,以便循环的每次迭代都会生成一个新字符串而不是修改它字符串。

答案 1 :(得分:0)

更具Ruby的解决方法是:

def subst(template, vars)
  template = template.dup
  derivations = [ ]

  while (template.sub!(/\<([a-zA-Z0-9_\-*]+)\>/) { vars[$1].sample })
    derivations << template.dup
  end

  derivations
end

在调用时可以起作用:

subst("The <animal> in the <object>", 'animal' => [ 'cat' ], 'object' => [ 'hat' ]);
# => ["The cat in the <object>", "The cat in the hat"]

请注意,如果您的某个替换文件包含<animal>等文本,其中包含<animal>等包含<animal>等文字的文字,则会进入无限循环...