Есть ли противоположность включить? для Ruby Arrays?

150

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

if [email protected]?(p.name)
  ...
end

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

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

if @players.does_not_include?(p.name)
  ...
end
  • 1
    это do правильный рубин? я получаю ошибку syntax error, unexpected end-of-input (работает, если я удалю do )
Теги:

11 ответов

312
Лучший ответ
if @players.exclude?(p.name)
    ...
end

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

Источник: Active Support Core Extensions (Руководства по Rails)

  • 1
    Полезно для тестов
  • 0
    Часто намного понятнее.
Показать ещё 4 комментария
85

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

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

Более подробную информацию о похожих методах вы можете посмотреть в Руководстве по стилю Ruby.

  • 0
    Upvote для руководства по стилю. Просто материал для чтения, который мне был нужен.
  • 1
    читается за одно утверждение. если много, то лучше использовать отрицание! или добавьте свой собственный метод в класс ruby array.
Показать ещё 3 комментария
10

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

unless @players.include?(p.name)
  ....
end
  • 0
    Я мог бы понизить это только, чтобы избежать призывов к кумовству ;-)
  • 0
    Чувак, со скоростью, с которой приходят ответы на этом сайте, я не знаю, получу ли я какую-либо репутацию без какого-либо добросовестного кумовства! :-D Ссылка на руководство по стилю - приятное прикосновение.
Показать ещё 1 комментарий
6
module Enumerable
  def does_not_include?(item)
    !include?(item)
  end
end

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

  • 1
    +1, unless это не нормально для показанного фрагмента, но условие может быть более сложным. Я думаю, что эти отрицательные методы удобно использовать, они допускают более декларативный код.
5

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

TL; DR

Использовать none? Передав это блок с == для сравнения:

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

Массив # включить?

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

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

Не Enumerable # ни?

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

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

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

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

Используйте, если.

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

Вы можете использовать

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

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

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

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

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

0

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

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

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

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

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

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

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

0

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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню