我在我的代码中有以下逻辑:

if !@players.include?(p.name)
  ...
end

@players是一个数组。有什么方法可以让我避免!?

理想情况下,这个代码片段应该是:

if @players.does_not_include?(p.name)
  ...
end

当前回答

只看Ruby:

博士TL;

用没有?传递一个带==的块用于比较:

[1, 2].include?(1)
  #=> true
[1, 2].none? { |n| 1 == n  }
  #=> false

数组#包括什么?接受一个参数,并使用==检查数组中的每个元素:

player = [1, 2, 3]
player.include?(1)
 #=> true

可列举的#没有?也可以接受一个参数,在这种情况下,它使用===进行比较。把相反的行为包括在内?我们省略参数,并使用==将块传递给它进行比较。

player.none? { |n| 7 == n }
 #=> true 
!player.include?(7)    #notice the '!'
 #=> true

在上面的例子中,我们实际上可以使用:

player.none?(7)
 #=> true

这是因为Integer#==和Integer#===是等价的。但考虑:

player.include?(Integer)
 #=> false
player.none?(Integer)
 #=> false

没有一个吗?返回false,因为Integer === 1 #=>为true。但真的是合法的不包含吗?方法应返回true。就像我们之前做的那样

player.none? { |e| Integer == e  }
 #=> true

其他回答

如果你对!-操作符的反对主要是它需要放在你的检查符前面,这会破坏你的输入流程,那么就有。!方法。你只需要把它放在check之后来反转布尔值:

if @players.include?(p.name).!

下面这个怎么样:

unless @players.include?(p.name)
  ....
end

试试这个,它是纯Ruby,所以不需要添加任何外围框架

if @players.include?(p.name) == false do 
  ...
end

我在类似的逻辑中挣扎了几天,在查看了几个论坛和问答板后,结果发现解决方案实际上非常简单。

这不是一个单一的方法,但链接计数和零工作:

[1, 2, 3].count(1).zero? # => false
[1, 2, 3].count(4).zero? # => true

它也适用于字符串:

"hello".count("l").zero? # => false
"hello".count("q").zero? # => true

只看Ruby:

博士TL;

用没有?传递一个带==的块用于比较:

[1, 2].include?(1)
  #=> true
[1, 2].none? { |n| 1 == n  }
  #=> false

数组#包括什么?接受一个参数,并使用==检查数组中的每个元素:

player = [1, 2, 3]
player.include?(1)
 #=> true

可列举的#没有?也可以接受一个参数,在这种情况下,它使用===进行比较。把相反的行为包括在内?我们省略参数,并使用==将块传递给它进行比较。

player.none? { |n| 7 == n }
 #=> true 
!player.include?(7)    #notice the '!'
 #=> true

在上面的例子中,我们实际上可以使用:

player.none?(7)
 #=> true

这是因为Integer#==和Integer#===是等价的。但考虑:

player.include?(Integer)
 #=> false
player.none?(Integer)
 #=> false

没有一个吗?返回false,因为Integer === 1 #=>为true。但真的是合法的不包含吗?方法应返回true。就像我们之前做的那样

player.none? { |e| Integer == e  }
 #=> true