Есть ли противоположность include? для массивов в Ruby?

у меня следующая логика в моем коде:

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

@players - это массив. Есть ли способ, чтобы я мог избежать !?

в идеале, этот фрагмент будет:

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

11 ответов


if @players.exclude?(p.name) do
    ...
end

ActiveSupport добавляет exclude? способ как Array и String. Это не чистый Рубин, но используется многими рубистами.


здесь вы идете:

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

вы могли бы взглянуть на Руководство По Стилю Ruby для получения дополнительной информации о подобных методах.


Как насчет следующего:

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

module Enumerable
  def does_not_include?(item)
    !include?(item)
  end
end

хорошо, но серьезно, если не работает нормально.


глядя только на Руби

TL; DR

использовать none? передача блока с помощью == для сравнения:

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

массив#include?

Array#include? принимает один аргумент и использует == для проверки каждого элемента в массиве:

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

перечисли#нет?

Enumerable#none? может также принять одно аргумент в этом случае использует === для сравнения. Чтобы получить противоположное поведение include? мы опускаем параметр и передаем ему блок, используя == для сравнения.

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

моменты

в приведенном выше примере мы можем фактически использовать:

player.none?(7)
 #=> true

потому что Integer#== и Integer#=== эквивалентны. Но подумайте:--26-->

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

none? возвращает false, потому что Integer === 1 #=> true. Но действительно легализоваться notinclude? метод должен возвратить true. Так же, как и раньше:

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

использовать, если.

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

используя unless отлично подходит для операторов с single include? предложения, но, например, когда вам нужно проверить включение чего-то в один Array но не в другом, использование include? С exclude? это гораздо удобнее.

if @players.include? && @spectators.exclude? do
  ....
end

но, как dizzy42 говорит выше, использование exclude? требуется ActiveSupport


попробуйте что-то вроде этого:

@players.include?(p.name) ? false : true

попробуйте это, это чистый Рубин, поэтому нет необходимости добавлять какие-либо периферийные фреймворки

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

Я боролся с подобной логикой в течение нескольких дней, и после проверки нескольких форумов и плат Q&A с небольшим успехом оказалось, что решение было довольно простым.


Я искал это для себя, нашел это, а затем решение. Люди используют запутанные методы и некоторые методы, которые не работают в определенных ситуациях или вообще не работают.

Я знаю, что уже слишком поздно, учитывая, что это было опубликовано 6 лет назад, но, надеюсь, будущие посетители найдут это (и, надеюсь, он может очистить их и ваш код.)

простое решение:

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

можно использовать

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

если не противоположно ли.

или вы можете использовать отклонение вы можете отклонить не обязательные элементы

@players.reject{|x| x==p.name}

после получения результатов вы можете сделать своей реализации