对另一个数组进行迭代,如果为真,则执行某项操作

Iterate through an array against another, and if true, do something

所以,如果你有一个句子作为字符串:

sentence = "Good morning, i'm doing well today."

然后转成子串数组:

words = sentence.split(" ")
> ["Good", "morning,", "i'm", "doing", "well", "today."]

并且您有一个包含以下记录的 WordBank 模型:

word_to_find: "i'm"
replace_with: "I'm"

我希望能够遍历单词,并对照 WordBank 进行检查。如果 return 为真,则用更正的替换项替换该子字符串。

words.each do |word|
  if WordBank.all.map { \f| f.word_to_find == word } 
    print "True"
  end
end
> True

words.each |word|
  if WordBank.all.map { |f| f.word_to_find == word }
    word == .replace_with
  end
end

其中 .replace_with,我需要能够调用相同的 WordBank 记录 returned true,但无法弄清楚如何。

所以最终结果应该return一个数组

> ["Good", "morning", "I'm", "doing", "well", "today."]

然后可以将其放回句子变量:

sentence = words.join(" ")

如果有更有效的方法,请随时告诉我。

sentence = "Good morning, i'm doing well today."
wordbank = [ { word_to_find: "i'm", replace_with: "I'm" } ]
wordbank.map { |f| sentence.gsub(f[:word_to_find], f[:replace_with]) }

我们可以创建一个词库哈希并循环遍历它以替换它而不进行检查,因为它只会替换句子中存在的单词。

gsub 用于替换句子中的单词,因为我们想就地替换我们包含了 ! 版本

wordbank = {
  "i'm": "I'm"
}
sentence = "Good morning, i'm doing well today."
wordbank.each do |k, v|
  sentence.gsub!(k.to_s, v)
end

假设您的词库超过 10000 个单词并且句子很小,那么更好的方法是循环遍历被 space 分割的句子并替换词库中存在的词。

wordbank = {
  "i'm": "I'm"
}
wordbank.default_proc = proc do |hsh, key|
   key.to_s
end
sentence = "Good morning, i'm doing well today."
words = sentence.split(/(\s+)/) # splitted with regex to preserve spaces 
                                # which will help to get the same string length
                                # when joined back together
words = words.map do |word|
   wordbank[word.to_sym]
end

注意:在 ruby 版本 3.0.0

上测试

我们得到:

sentence = "Good morning, i'm doing well today."
changes = { "i'm"=>"I'm" }

首先构造一个新的散列:

h = Hash.new { |h,k| k }.merge(changes)
  #=> {"i'm"=>"I'm"}

我用过Hash::new that takes a block to create an empty hash into which changes is merged. h is seen to have the same keys and values as changes but it now has a Hash#default_proc的形式:

h.default_proc
  #=> #<Proc:0x00007f80970fe190 <main>:3>

因此,

h["i'm"]
  #=> "I'm"

正常(因为 h 有一个键 "i'm"),但是如果 h 没有键,比如 "well",可以看出默认过程原因

h["well"]

到return是参数("well").

因此,我们可以使用 String#gsub 的形式,将散列作为其可选的第二个参数:

sentence.gsub(/[\w']+/, h)
  #=> "Good morning, I'm doing well today."

正则表达式/[\w']+/匹配字符class[\w']中的一个或多个字符,即单词字符和撇号。


考虑第二个例子。

sentence = "Good morning,     i'm good today."
changes = { "i'm"=>"I'm", "morning"=>"evening", "Good"=>"Bad", "good"=>"bad" }
h = Hash.new { |h,k| k }.merge(changes)
  #=> {"i'm"=>"I'm", "morning"=>"evening", "Good"=>"Bad", "good"=>"bad"}
sentence.gsub(/[\w']+/, h)
  #=> "Bad evening,     I'm bad today."

除其他事项外,请注意额外的空格会被保留,而如果 sentence 被分解成单词,这些单词会被修改然后合并。

由于要修改words中的元素,使用的方法是map!。假设 wordbank 是一个 Hash,将单词映射到它们的替换,shis 将是:

words.map! do
  |element|
  wordbank[element] || element
end

当然,wordbank 以不同的方式实施取决于您。