У моєму коді є така логіка:
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
. Це не чистий Рубін, але його використовує багато рубістів.
Джерело: Основні розширення з підтримкою (Посібники по рейках)
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
Дивлячись лише на Рубі:
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?
з exclude?
набагато привітніше.
if @players.include? && @spectators.exclude? do
....
end
Але як запаморочення говорить вище, для використання 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