Есть ли противоположность 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 для получения дополнительной информации о подобных методах.
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
отлично подходит для операторов с single include?
предложения, но, например, когда вам нужно проверить включение чего-то в один Array
но не в другом, использование include?
С exclude?
это гораздо удобнее.
if @players.include? && @spectators.exclude? do
....
end
но, как dizzy42 говорит выше, использование exclude?
требуется ActiveSupport
попробуйте это, это чистый Рубин, поэтому нет необходимости добавлять какие-либо периферийные фреймворки
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}
после получения результатов вы можете сделать своей реализации