J'ai une très longue déclaration conditionnelle comme celle-ci:
if(test.type == 'itema' || test.type == 'itemb' || test.type == 'itemc' || test.type == 'itemd'){
// do something.
}
Je me demandais si je pouvais refactoriser cette expression / déclaration sous une forme plus concise.
Une idée sur la façon d'y parvenir?
javascript
if-statement
FlyingCat
la source
la source
in
?||
. (2)switch
déclarations. (3) regex. (4)~
. jsperf.com/if-statements-test-techsinRéponses:
Mettez vos valeurs dans un tableau et vérifiez si votre élément est dans le tableau:
Si un navigateur que vous prenez en charge ne dispose pas de la
Array#includes
méthode, vous pouvez utiliser ce polyfill .Brève explication du
~
raccourci tilde:Au lieu de vérifier si le résultat de
indexOf
est>= 0
, il y a un joli petit raccourci:Voici le violon: http://jsfiddle.net/HYJvK/
Comment cela marche-t-il? Si un élément est trouvé dans le tableau,
indexOf
renvoie son index. Si l'article n'a pas été trouvé, il reviendra-1
. Sans entrer dans les détails, le~
est un opérateur NOT au niveau du bit , qui ne retournera0
que pour-1
.J'aime utiliser le
~
raccourci, car il est plus succinct que de faire une comparaison sur la valeur de retour. Je souhaite que JavaScript ait unein_array
fonction qui renvoie directement un booléen (similaire à PHP), mais c'est juste un vœu pieux ( Mise à jour: c'est maintenant le cas. Il est appeléincludes
. Voir ci-dessus). Notez que jQueryinArray
, tout en partageant la signature de méthode PHP, imite en fait laindexOf
fonctionnalité native (ce qui est utile dans différents cas, si l'index est ce que vous recherchez vraiment).Remarque importante: l' utilisation du raccourci tilde semble être controversée, car certains pensent avec véhémence que le code n'est pas assez clair et doit être évité à tout prix (voir les commentaires sur cette réponse). Si vous partagez leur sentiment, vous devez vous en tenir à la
.indexOf(...) >= 0
solution.Une explication un peu plus longue:
Les entiers en JavaScript sont signés, ce qui signifie que le bit le plus à gauche est réservé comme bit de signe; un drapeau pour indiquer si le nombre est positif ou négatif, avec un
1
négatif.Voici quelques exemples de nombres positifs au format binaire 32 bits:
Voici maintenant ces mêmes chiffres, mais négatifs:
Pourquoi des combinaisons aussi étranges pour les nombres négatifs? Facile. Un nombre négatif est simplement l'inverse du nombre positif + 1; l'ajout du nombre négatif au nombre positif doit toujours produire
0
.Pour comprendre cela, faisons une simple arithmétique binaire.
Voici comment nous ajouterions
-1
à+1
:Et voici comment nous ajouterions
-15
à+15
:Comment obtenons-nous ces résultats? En faisant des ajouts réguliers, comme on nous a enseigné à l'école: vous commencez à la colonne la plus à droite et vous additionnez toutes les lignes. Si la somme est supérieure au plus grand nombre à un chiffre (qui en décimal est
9
, mais en binaire est1
), nous reportons le reste à la colonne suivante.Maintenant, comme vous le remarquerez, lorsque vous ajoutez un nombre négatif à son nombre positif, la colonne la plus à droite qui n'est pas tout
0
s aura toujours deux1
s, ce qui, une fois additionné, donnera2
. La représentation binaire de deux étant10
, nous portons le1
à la colonne suivante, et mettons un0
pour le résultat dans la première colonne. Toutes les autres colonnes à gauche n'ont qu'une seule ligne avec un1
, donc le report1
de la colonne précédente s'additionnera à nouveau2
, qui sera ensuite reporté ... Ce processus se répète jusqu'à ce que nous arrivions à la colonne la plus à gauche, où le1
à reporter n'a nulle part où aller, donc il déborde et se perd, et nous nous retrouvons avec des0
s partout.Ce système est appelé Complément 2 . Vous pouvez en savoir plus ici:
Représentation complémentaire de 2 pour les entiers signés .
Maintenant que le cours intensif du complément de 2 est terminé, vous remarquerez que
-1
c'est le seul nombre dont la représentation binaire est1
de partout.En utilisant l'
~
opérateur NOT au niveau du bit, tous les bits d'un nombre donné sont inversés. La seule façon de revenir en0
arrière de l'inversion de tous les bits est de commencer avec des1
«all across».Donc, tout cela était une longue façon de dire qui
~n
ne reviendra que0
sin
c'est le cas-1
.la source
!== -1
de toute manière imaginable? La logique booléenne explicite n'est-elle pas plus appropriée que d'utiliser implicitement la fausseté de zéro?!= -1
.Vous pouvez utiliser l'instruction switch avec fall thru:
la source
||
) sur Chrome. Voir jsperf.com/if-statements-test-techsinUtilisation de la science: vous devez faire ce que l'idfah a dit et ceci pour une vitesse plus rapide tout en gardant le code court:
CECI EST PLUS RAPIDE QUE LA
~
Méthodehttp://jsperf.com/if-statements-test-techsin (Ensemble supérieur: Chrome, ensemble inférieur: Firefox)
Conclusion :
Si les possibilités sont peu et vous savez que certains d'entre eux sont plus susceptibles de se produire que vous obtenez des performances maximales
if ||
,switch fall through
etif(obj[keyval])
.Si les possibilités sont nombreuses et que n'importe laquelle d'entre elles pourrait être la plus présente, en d'autres termes, vous ne pouvez pas savoir laquelle est la plus susceptible de se produire que vous obtenez le plus de performances de la recherche d'objets
if(obj[keyval])
etregex
si cela vous convient.http://jsperf.com/if-statements-test-techsin/12
Je mettrai à jour si quelque chose de nouveau arrive.
la source
switch case
est la méthode la plus rapide?if ( ...||...||...)...
obj["itemX"]
est extrêmement rapide si n est grand. Fondamentalement, ce qui est rapide dépend du contexte. S'amuser.Si vous comparez à des chaînes et qu'il existe un modèle, envisagez d'utiliser des expressions régulières.
Sinon, je soupçonne que tenter de le raccourcir ne fera qu'obscurcir votre code. Pensez simplement à envelopper les lignes pour le rendre joli.
la source
(test.type == 'itemf' && foo.mode == 'detailed')
)L'utilisation d'un objet comme tableau associatif est une chose assez courante, mais comme JavaScript n'a pas d'ensemble natif, vous pouvez également utiliser des objets comme ensembles bon marché.
la source
if
Le conditionnel de l' instruction @dcarson OP prend 78 caractères si vous supprimez tous les espaces. 54 prend le mien si vous écrivez comme ceci:test.type in {"itema":1,"itemb":1,"itemc":1,"itemd":1}
. Fondamentalement, il utilise quatre caractères pour chaque utilisation de deux mines pour chaque clé supplémentaire.ou si les articles ne sont pas aussi uniformes, alors:
la source
Excellentes réponses, mais vous pourriez rendre le code beaucoup plus lisible en enveloppant l'un d'entre eux dans une fonction.
Ceci est complexe si la déclaration, lorsque vous (ou quelqu'un d'autre) lisez le code dans un an, vous allez parcourir pour trouver la section pour comprendre ce qui se passe. Une déclaration avec ce niveau de logique métier vous fera trébucher pendant quelques secondes pendant que vous travaillez sur ce que vous testez. Où en tant que code comme celui-ci, vous permettra de continuer la numérisation.
Nommez votre fonction explicitement pour que ce que vous testez soit immédiatement évident et que votre code soit beaucoup plus facile à analyser et à comprendre.
la source
// CheckIfBusinessRuleIsTrue
?Vous pouvez mettre toutes les réponses dans un ensemble Javascript , puis simplement appeler
.contains()
l'ensemble.Vous devez toujours déclarer tout le contenu, mais l'appel en ligne sera plus court.
Quelque chose comme:
la source
L'une de mes façons préférées d'y parvenir est d'utiliser une bibliothèque telle que underscore.js ...
http://underscorejs.org/#some
la source
contains
est sans doute une meilleure solution quesome
some
c'est une fonction sur le prototype Array dans EC5.une autre façon ou une autre façon géniale que j'ai trouvée est celle-ci ...
bien sûr, comme vous pouvez le voir, cela va encore plus loin et les rend faciles à suivre la logique.
http://snook.ca/archives/javascript/testing_for_a_v
en utilisant des opérateurs tels que ~ && || ((), ()) ~~ ne convient que si votre code se rompt plus tard. Vous ne saurez pas par où commencer. La lisibilité est donc GRANDE.
si vous le devez, vous pourriez le raccourcir.
et si vous voulez faire l'inverse
la source
Utilisez simplement une
switch
instruction au lieu d'uneif
instruction:Switch
fonctionne également plus rapidement que de comparer de nombreuses conditions dans unif
la source
Pour de très longues listes de chaînes, cette idée permettrait d'économiser quelques caractères (sans dire que je le recommanderais dans la vraie vie, mais cela devrait fonctionner).
Choisissez un caractère dont vous savez qu'il n'apparaîtra pas dans votre test.type, utilisez-le comme délimiteur, collez-les tous dans une longue chaîne et recherchez que:
Si vos chaînes sont davantage contraintes, vous pouvez même omettre les délimiteurs ...
... mais vous devrez faire attention aux faux positifs dans ce cas (par exemple, "embite" correspondrait dans cette version)
la source
Pour la lisibilité, créez une fonction pour le test (oui, une fonction sur une ligne):
alors appelez-le:
la source
Je pense qu'il y a 2 objectifs lors de l'écriture de ce type de condition if.
En tant que tel, parfois le n ° 1 peut être le plus rapide, mais je prendrai le n ° 2 pour une maintenance facile plus tard. Selon le scénario, j'opterai souvent pour une variante de la réponse de Walter.
Pour commencer, j'ai une fonction disponible globalement dans le cadre de ma bibliothèque existante.
et ensuite, lorsque je veux réellement exécuter une condition if similaire à la vôtre, je crée un objet avec une liste des valeurs valides:
Ce n'est pas aussi rapide qu'une instruction switch / case et un peu plus verbeux que certains des autres exemples, mais je reçois souvent une réutilisation de l'objet ailleurs dans le code, ce qui peut être très pratique.
En utilisant l'un des échantillons jsperf ci-dessus, j'ai ajouté ce test et une variation pour comparer les vitesses. http://jsperf.com/if-statements-test-techsin/6 La chose la plus intéressante que j'ai notée est que certains combos de tests dans Firefox sont beaucoup plus rapides que même Chrome.
la source
Cela peut être résolu avec une simple boucle for:
Nous utilisons la première section de la boucle for pour initialiser les arguments que vous souhaitez mettre en correspondance, la deuxième section pour arrêter l'exécution de la boucle for et la troisième section pour que la boucle se termine finalement.
la source