W moim kodzie mam następującą logikę:
if !@players.include?(p.name)
...
end
@players
jest tablicą. Czy istnieje metoda, dzięki której mogę uniknąć !
?
Najlepiej byłoby, gdyby ten fragment był:
if @players.does_not_include?(p.name)
...
end
W moim kodzie mam następującą logikę:
if !@players.include?(p.name)
...
end
@players
jest tablicą. Czy istnieje metoda, dzięki której mogę uniknąć !
?
Najlepiej byłoby, gdyby ten fragment był:
if @players.does_not_include?(p.name)
...
end
Odpowiedzi:
if @players.exclude?(p.name)
...
end
ActiveSupport dodaje exclude?
metodę Array
, Hash
oraz String
. To nie jest czysty rubin, ale jest używany przez WIELU rubinów.
Źródło: Główne rozszerzenia Active Support (przewodniki po szynach)
require 'active_support/core_ext/enumerable'
Proszę bardzo:
unless @players.include?(p.name)
...
end
Możesz zajrzeć do Przewodnika po stylu Ruby, aby uzyskać więcej informacji na temat podobnych technik.
if flag unless @players.include?(p.name)
jest niezręczny i if flag && !@players.include?(p.name)
używa negacji.
if
tylko niech true
przechodzą stan, unless
pozwala przejść false
i nil
. To czasami prowadzi do trudnych do znalezienia błędów. Dlatego wolęexclude?
Co powiesz na następujące:
unless @players.include?(p.name)
....
end
Patrząc tylko na Ruby:
TL; DR
Użyj do porównania none?
bloku z ==
do:
[1, 2].include?(1)
#=> true
[1, 2].none? { |n| 1 == n }
#=> false
Array#include?
akceptuje jeden argument i używa ==
do sprawdzenia każdego elementu w tablicy:
player = [1, 2, 3]
player.include?(1)
#=> true
Enumerable#none?
może również zaakceptować jeden argument, w którym to przypadku używa go ===
do porównania. Aby uzyskać przeciwne zachowanie include?
, pomijamy parametr i przekazujemy go do bloku za pomocą ==
porównania.
player.none? { |n| 7 == n }
#=> true
!player.include?(7) #notice the '!'
#=> true
W powyższym przykładzie możemy faktycznie użyć:
player.none?(7)
#=> true
To dlatego, że Integer#==
i Integer#===
są równoważne. Ale zastanów się:
player.include?(Integer)
#=> false
player.none?(Integer)
#=> false
none?
zwraca false
ponieważ Integer === 1 #=> true
. Ale naprawdę legalna notinclude?
metoda powinna powrócić true
. Tak jak wcześniej:
player.none? { |e| Integer == e }
#=> true
module Enumerable
def does_not_include?(item)
!include?(item)
end
end
Ok, ale poważnie, chyba że działa dobrze.
unless
jest w porządku dla pokazanego fragmentu, ale warunek może być bardziej złożony. Myślę, że warto mieć te zanegowane metody, które pozwalają na bardziej deklaratywny kod.
Użyj unless
:
unless @players.include?(p.name) do
...
end
Używanie unless
jest w porządku dla instrukcji z pojedynczymi include?
klauzulami, ale na przykład, gdy trzeba sprawdzić włączenie czegoś w jednym, Array
ale nie w drugim, użycie include?
z exclude?
jest znacznie bardziej przyjazne.
if @players.include? && @spectators.exclude? do
....
end
Ale jak mówi dizzy42 powyżej, użycie exclude?
wymaga ActiveSupport
Patrzyłem na to dla siebie, znalazłem to, a potem rozwiązanie. Ludzie używają mylących metod i niektórych metod, które nie działają w określonych sytuacjach lub wcale.
Wiem, że jest już za późno, biorąc pod uwagę, że został opublikowany 6 lat temu, ale mam nadzieję, że przyszli odwiedzający to znajdą (i mam nadzieję, że to może wyczyścić ich i twój kod).
Proste rozwiązanie:
if not @players.include?(p.name) do
....
end
do
prawidłowy rubin? dostaję błądsyntax error, unexpected end-of-input
(działa, jeślido