删除存在于另一个数组中的数组元素
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}
如果你想获得 words
数组中存在的禁用词列表,你可以使用 .select
:
words.select {|w| redacted.include? w}
它也可以工作。
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.
有单词表和禁用词表。我想浏览单词列表并编辑所有禁用的单词。这就是我最终做的(注意 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}
如果你想获得 words
数组中存在的禁用词列表,你可以使用 .select
:
words.select {|w| redacted.include? w}
它也可以工作。
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.