删除存在于另一个数组中的数组元素

Remove array elements that are present in another array

有单词表和禁用词表。我想浏览单词列表并编辑所有禁用的单词。这就是我最终做的(注意 catched 布尔值):

puts "Give input text:"
text = gets.chomp
puts "Give redacted word:"
redacted = gets.chomp

words = text.split(" ")
redacted = redacted.split(" ")
catched = false

words.each do |word|
  redacted.each do |redacted_word|
    if word == redacted_word
        catched = true
        print "REDACTED "
        break
    end
  end
    if catched == true
        catched = false
    else
        print word + " "
    end
end

有什么proper/efficient方法吗?

您可以使用 .reject 排除 redacted 数组中存在的所有禁用词:

words.reject {|w| redacted.include? w}

Demo

如果你想获得 words 数组中存在的禁用词列表,你可以使用 .select:

words.select {|w| redacted.include? w}

Demo

它也可以工作。

words - redacted

+,-,&,这些方法非常简单好用

irb(main):016:0> words = ["a", "b", "a", "c"]
=> ["a", "b", "a", "c"]
irb(main):017:0> redacted = ["a", "b"]
=> ["a", "b"]
irb(main):018:0> words - redacted
=> ["c"]
irb(main):019:0> words + redacted
=> ["a", "b", "a", "c", "a", "b"]
irb(main):020:0> words & redacted
=> ["a", "b"]

这可能有点多 'elegant'。我不知道它是否比您的解决方案更有效。

puts "Give input text:"
original_text = gets.chomp
puts "Give redacted word:"
redacted = gets.chomp

redacted_words = redacted.split

print(
  redacted_words.inject(original_text) do |text, redacted_word|
    text.gsub(/\b#{redacted_word}\b/, 'REDACTED')
  end
)

这是怎么回事?

  • 我使用 String#split 没有参数,因为 ' ' is the default,无论如何。
  • 对于 Array#inject,将对数组中的每个元素执行以下块(从 do 开始并在 end 结束——在这种情况下,我们的禁用词列表。
    • 在每一轮中,块的第二个参数将是数组中的相应元素
    • 块的第一个参数将是上一轮块的 return 值。对于第一轮,将使用注入函数的参数(在我们的例子中 original_text)。
    • 来自上一轮的块的 return 值将用作注入函数的 return 值。
  • 在块中,我替换了文本中所有出现的当前处理的编辑词。
    • String#gsub 执行 g 全局 substitution
    • 作为要替换的模式,我使用正则表达式 (/.../)。除了,它不是真正的文字,因为我正在对其执行字符串替换 (#{...}) 以将当前处理的编辑词放入其中。
    • 在正则表达式中,我用 \b word boundary matchers 包围了要编辑的词。它们匹配字母数字字符和非字母数字字符(反之亦然)之间的边界,而不匹配任何字符本身。 (它们匹配字符之间的零长度 'position'。)如果字符串以字母数字字符开头或结尾,\b 也将分别匹配字符串的开头或结尾,以便我们可以使用它匹配整个单词。
  • inject的结果(这是最后一次执行块的结果,即所有替换发生时的文本)作为参数传递给print,这将输出现在编辑的文本。

注意除了你的解决方案,我的解决方案不会将标点符号视为相邻单词的一部分。

另外请注意我的解决方案容易受到正则表达式注入的攻击。

示例 1:

Give input text:
A fnord is a fnord.
Give redacted word:
ford fnord foo

我的输出:

A REDACTED is a REDACTED.

你的输出:

A REDACTED is a fnord.

示例 2:

Give input text:
A fnord is a fnord.
Give redacted word:
fnord.

我的输出:

A REDACTEDis a fnord.

(请注意 . 是如何被解释为匹配任何字符的。)

你的输出:

A fnord is a REDACTED.