Ruby '中的If语句;数组#每个';返回';正确';仅在最后一个元素上

Ruby '中的If语句;数组#每个';返回';正确';仅在最后一个元素上,ruby,Ruby,我正在为我的discord服务器编写一个bot,我想作为亵渎过滤器。我从一个文本文件中读取一个坏单词列表,并将它们存储在一个数组中。每当用户发送消息时(在bot正在收听的频道中),bot就会检查该消息是否包含一个或多个这些坏单词。为此,我使用以下代码: badWords.each { |badword| if content.downcase.include? badword ... end } 我的问题是,只有当消息内容中的坏字与数组中的最后一个匹配时,if语句才会返回tru

我正在为我的discord服务器编写一个bot,我想作为亵渎过滤器。我从一个文本文件中读取一个坏单词列表,并将它们存储在一个数组中。每当用户发送消息时(在bot正在收听的频道中),bot就会检查该消息是否包含一个或多个这些坏单词。为此,我使用以下代码:

badWords.each { |badword|
  if content.downcase.include? badword
    ...
  end
}
我的问题是,只有当消息内容中的坏字与数组中的最后一个匹配时,if语句才会返回
true
。如果它与数组的任何其他元素匹配,则返回
false


Array#每个
是否有我误解的功能?

尝试
去除一个坏词,因为它最后可能有
\n
符号

if content.downcase.include?(badword.strip)

我会将您的代码分解成更小的部分,这样您就可以更好地理解正在发生的事情,然后使用Ruby中的一个来帮助使事情更加简洁。另外,让我们使用snake_大小写的Ruby约定(
bad_words
,而不是
bad words

首先,让我们确保您的
坏单词
数组不包含任何不需要的字符。最好只修改一次
bad_words
集合,而不是每次都迭代修改每个元素

当我们进行此项工作时,由于我们的集合不包含重复项,并且由于我们将多次搜索匹配元素,因此通过将数组转换为集合,我们可以大大提高效率:

require 'set'
bad_words = bad_words.map(&:strip).to_set
接下来,让我们编写一个方法来检查内容是否包含坏单词。我们将在方法名称的末尾打一个问号,表示它返回一个布尔值:

def profane?(content)
  bad_words.any? { |bad_word| content.include?(bad_word) }
end
如果传递到以下块的任何项返回
true
,则
#any?
方法返回true

现在,您的操作代码可以调用
亵渎?
并采取适当的操作:

def filter_bad_words(content)
  if profane?(content)
    bot.send_message(event.channel.id, "Sorry #{event.user.name}, this message made my profanity senses tingle!")
    bot.send_message(344559522003812354, "PROFANITY WARNING!!\n user: #{event.user.name}\n message: #{event.content}\n Please check if it is a cause for a warning. Use !?warn to give the user a warning.")
    event.message.delete
    true
  end
end

如果内容是亵渎的,我已经让方法返回
true
,如果内容不是亵渎的,默认情况下它将返回
nil
。如果愿意,您可以使用不同的返回值,并且可以根据该响应采取进一步的操作。

谢谢您的回答,它在调试问题时帮助了我很多。解决方案是@AlexKojin发布的。好吧,但您意识到,如果内容包含5个坏单词,您将向用户发送5条消息,然后向日志发送5条消息,然后尝试删除事件。消息5次。此外,如果您有一个包含50个坏单词的列表,您将测试每个坏单词,即使第一个坏单词包含在
内容中。我的解决方案解决了这两个问题。非常感谢,这似乎就是问题所在。每次评估新的
内容
时,都会将
.strip
单独应用于每个坏词。