У меня есть следующая логика в моем коде:
if !@players.include?(p.name)
...
end
@players
это массив. Есть ли способ, чтобы я мог избежать !
?
В идеале этот фрагмент будет:
if @players.does_not_include?(p.name)
...
end
У меня есть следующая логика в моем коде:
if !@players.include?(p.name)
...
end
@players
это массив. Есть ли способ, чтобы я мог избежать !
?
В идеале этот фрагмент будет:
if @players.does_not_include?(p.name)
...
end
Ответы:
if @players.exclude?(p.name)
...
end
ActiveSupport добавляет exclude?
метод Array
, Hash
, и String
. Это не чистый Ruby, но используется большим количеством рубинов.
Источник: Active Support Core Extensions (Руководства по Rails)
require 'active_support/core_ext/enumerable'
Ну вот:
unless @players.include?(p.name)
...
end
Вы можете взглянуть на Руководство по стилю Ruby для получения дополнительной информации о подобных методах.
if flag unless @players.include?(p.name)
неудобно и if flag && !@players.include?(p.name)
использует отрицание.
if
пусть true
проходит только условие, unless
пропускает false
и nil
. Это иногда приводит к трудностям поиска ошибок. Поэтому я предпочитаюexclude?
Как насчет следующего:
unless @players.include?(p.name)
....
end
Глядя только на Ruby:
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#none?
Можно также принять один аргумент, в этом случае он использует ===
для сравнения. Чтобы получить противоположное поведение, 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
module Enumerable
def does_not_include?(item)
!include?(item)
end
end
Хорошо, но если серьезно, то разве работает нормально.
unless
это нормально для показанного фрагмента, но условие может быть более сложным. Я думаю, что эти отрицательные методы удобно использовать, они допускают более декларативный код.
Используйте unless
:
unless @players.include?(p.name) do
...
end
Использование unless
отлично подходит для операторов с одиночными include?
предложениями, но, например, когда вам нужно проверить включение чего-либо в одном, Array
а не в другом, использование include?
with exclude?
намного удобнее.
if @players.include? && @spectators.exclude? do
....
end
Но, как говорит dizzy42 выше, использование exclude?
ActiveSupport требует
Попробуйте, это чистый Ruby, поэтому нет необходимости добавлять какие-либо периферийные платформы
if @players.include?(p.name) == false do
...
end
Я боролся с подобной логикой в течение нескольких дней, и после небольшой проверки нескольких форумов и форумов, посвященных вопросам и ответам, оказалось, что решение было на самом деле довольно простым.
Я искал это для себя, нашел это, а затем и решение. Люди используют запутанные методы и некоторые методы, которые не работают в определенных ситуациях или не работают вообще.
Я знаю, что сейчас слишком поздно, учитывая, что это было опубликовано 6 лет назад, но, надеюсь, будущие посетители найдут это (и, надеюсь, это может очистить их и ваш код).
Простое решение:
if not @players.include?(p.name) do
....
end
do
действительным рубин? я получаю ошибкуsyntax error, unexpected end-of-input
(работает, если яdo