J'ai la logique suivante dans mon code:
if !@players.include?(p.name)
...
end
@players
est un tableau. Existe-t-il une méthode pour éviter le !
?
Idéalement, cet extrait serait:
if @players.does_not_include?(p.name)
...
end
J'ai la logique suivante dans mon code:
if !@players.include?(p.name)
...
end
@players
est un tableau. Existe-t-il une méthode pour éviter le !
?
Idéalement, cet extrait serait:
if @players.does_not_include?(p.name)
...
end
Réponses:
if @players.exclude?(p.name)
...
end
ActiveSupport ajoute la exclude?
méthode Array
, Hash
et String
. Ce n'est pas du pur Ruby, mais est utilisé par BEAUCOUP de rubisistes.
Source: Extensions de base de support actif (guides de rails)
require 'active_support/core_ext/enumerable'
Voici:
unless @players.include?(p.name)
...
end
Vous pouvez consulter le Ruby Style Guide pour plus d'informations sur des techniques similaires.
if flag unless @players.include?(p.name)
est maladroit et if flag && !@players.include?(p.name)
utilise la négation.
if
laissez seulement true
passer la condition, unless
laissez passer false
et nil
. Cela conduit parfois à des bogues difficiles à trouver. Par conséquent, je préfèreexclude?
Que diriez-vous de ce qui suit:
unless @players.include?(p.name)
....
end
En regardant Ruby uniquement:
TL; DR
Utilisez en none?
passant un bloc avec ==
pour la comparaison:
[1, 2].include?(1)
#=> true
[1, 2].none? { |n| 1 == n }
#=> false
Array#include?
accepte un argument et utilise ==
pour vérifier chaque élément du tableau:
player = [1, 2, 3]
player.include?(1)
#=> true
Enumerable#none?
peut également accepter un argument auquel cas il l'utilise ===
pour la comparaison. Pour obtenir le comportement opposé, include?
nous omettons le paramètre et lui passons un bloc en utilisant ==
pour la comparaison.
player.none? { |n| 7 == n }
#=> true
!player.include?(7) #notice the '!'
#=> true
Dans l'exemple ci-dessus, nous pouvons en fait utiliser:
player.none?(7)
#=> true
C'est parce que Integer#==
et Integer#===
sont équivalents. Mais considérez:
player.include?(Integer)
#=> false
player.none?(Integer)
#=> false
none?
revient false
parce que Integer === 1 #=> true
. Mais vraiment une notinclude?
méthode légitime devrait revenir true
. Donc, comme nous l'avons fait auparavant:
player.none? { |e| Integer == e }
#=> true
module Enumerable
def does_not_include?(item)
!include?(item)
end
end
Ok, mais sérieusement, le moins fonctionne bien.
unless
c'est correct pour l'extrait affiché, mais la condition peut être plus complexe. Je pense que c'est pratique d'avoir ces méthodes négatives, elles permettent un code plus déclaratif.
Utilisez unless
:
unless @players.include?(p.name) do
...
end
L'utilisation unless
est bien pour les instructions avec des include?
clauses simples mais, par exemple, lorsque vous devez vérifier l'inclusion de quelque chose dans l'une Array
mais pas dans une autre, l'utilisation de include?
with exclude?
est beaucoup plus conviviale.
if @players.include? && @spectators.exclude? do
....
end
Mais comme le dit vertige42 ci-dessus, l'utilisation de exclude?
nécessite ActiveSupport
Essayez ceci, c'est du pur Ruby, il n'est donc pas nécessaire d'ajouter des frameworks périphériques
if @players.include?(p.name) == false do
...
end
J'ai eu des difficultés avec une logique similaire pendant quelques jours, et après avoir vérifié plusieurs forums et tableaux de questions-réponses en vain, il s'est avéré que la solution était en fait assez simple.
J'étais à la recherche de cela par moi-même, j'ai trouvé ceci, puis une solution. Les gens utilisent des méthodes déroutantes et certaines méthodes qui ne fonctionnent pas dans certaines situations ou pas du tout.
Je sais qu'il est trop tard maintenant, étant donné que cela a été publié il y a 6 ans, mais j'espère que les futurs visiteurs le trouveront (et j'espère que cela pourra nettoyer leur code et le vôtre.)
Solution simple:
if not @players.include?(p.name) do
....
end
do
rubis valide? j'obtiens une erreursyntax error, unexpected end-of-input
(fonctionne si je supprime ledo
)