Comment raccourcir mes instructions conditionnelles
J'ai une très longue instruction conditionnelle comme suit:
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 dans une forme plus concise.
Aucune idée sur comment faire?
- Vous pouvez les mettre dans un tableau et utiliser
in
? - snook.ca/archives/javascript/testing_for_a_v
- maintenant, seulement si quelqu'un pouvait vérifier lequel est le plus rapide
- cela peut être un choc pour tout le monde mais ce que l'OP a est un gagnant clair dans la vitesse!!!!!!! Peut-être à cause du navigateur optimiser pour cela beaucoup.. Résultats: (1) si avec
||
. (2)switch
consolidés. (3) regex. (4)~
. jsperf.com/if-statements-test-techsin - Vous pouvez également être en approchant de cette façon le mal. Dans ce cas, ces 4 types ont quelque chose en commun. Quel est-il? Si nous prenons cela pour un cas plus extrême, que si nous devions ajouter 10 autres types de correspondre à cette condition. Ou 100? S'il n'y avait plus, vous n'auriez probablement pas envisager de recourir à cette solution, ou de toute autres propositions. Vous êtes témoins d'un grand si l'instruction de ce genre, et de penser que c'est une odeur de code, ce qui est un bon signe. Votre meilleur moyen de le rendre plus concis serait si vous pouviez écrire if (test.your_common_condition). C'est plus facile à comprendre dans ce contexte, et plus extensible.
- Lire: Optimiser OU SI
- En python ce serais simplement
if test.type in ('itema', 'itemb', ...):
- Ces résultats sont très bizarre lorsque l'on compare les résultats entre Firefox & Chrome, que la différence est ÉNORME.
- ff a battu chrome en js vitesse récemment, donc oui.
- Cette question est actuellement un double de double de double de double de double. (this -> Javascript formatage si la condition -> Javascript: Comparaison de la Valeur UNIQUE à l'Encontre de PLUSIEURS Valeurs avec OU Opérandes -> Javascript si l'instruction avec plusieurs admissibilité-conditions ->Javascript Si l'instruction utilisée pour vérifier les extensions de fichier ne fonctionne pas)
Vous devez vous connecter pour publier un commentaire.
Mettre vos valeurs dans un tableau, et de vérifier si votre article est dans le tableau:
Si le navigateur vous le soutien n'a pas le
Array#includes
méthode, vous pouvez utiliser cette polyfill.Courte explication de la
~
tilde raccourci:Au lieu de vérifier si le résultat de
indexOf
est>= 0
, il est un agréable petit raccourci:Ici est le violon: http://jsfiddle.net/HYJvK/
Comment cela fonctionne? Si un élément est trouvé dans le tableau,
indexOf
retourne son index. Si l'élément n'a pas été trouvé, il va revenir-1
. Sans entrer dans trop de détails, le~
est un not au niveau du bit opérateur, qui sera de retour0
seulement pour-1
.J'ai comme l'utilisation de la
~
raccourci, car il est plus concis que de faire une comparaison de la valeur de retour. Je souhaite JavaScript serait unin_array
fonction qui retourne un Booléen directement (similaire à PHP), mais c'est juste un vœu pieux (mise à Jour: c'est maintenant. Il est appeléincludes
. Voir ci-dessus). Notez que jQueryinArray
, tandis que le partage de PHP à la signature de la méthode, imite en fait le natifindexOf
fonctionnalité (ce qui est utile dans différents cas, si l'index est ce que vous êtes vraiment après).Remarque importante: à l'Aide de la tilde raccourci semble être plongé dans la controverse, comme certains avec véhémence crois que le code n'est pas suffisamment claire et doit être évité à tous les frais (voir les commentaires sur cette réponse). Si vous partagez leur sentiment, vous devez vous en tenir à la
.indexOf(...) >= 0
solution.Un peu plus d'explication:
Entiers en JavaScript sont signés, ce qui signifie que la partie gauche du bit est réservé que le bit de signe; un drapeau pour indiquer si le nombre est positif ou négatif, avec un
1
être négatif.Voici quelques exemples de nombres positifs en binaire de 32 bits format:
Voici maintenant de ces mêmes nombres, mais négatif:
Pourquoi ces étranges combinaisons pour les nombres négatifs? Simple. Un nombre négatif est tout simplement l'inverse du nombre positif + 1; ajouter le numéro du négatif au positif numéro doit toujours céder
0
.Pour comprendre cela, nous allons faire quelques simple arithmétique binaire.
Voici comment nous pourrions ajouter
-1
à+1
:Et voici comment nous pourrions ajouter
-15
à+15
:Comment pouvons-nous obtenir ces résultats? Par la pratique régulière de plus, la manière dont il nous a été enseigné à l'école: vous commencez à la colonne la plus à droite, et vous additionnez toutes les lignes. Si la somme est plus grande que le plus grand nombre (qui en décimal est
9
, mais en binaire est1
) nous portons le reste à la colonne suivante.Maintenant, comme vous le verrez, lors de l'ajout d'un nombre négatif à son nombre positif, la colonne la plus à droite ce n'est pas tout
0
s auront toujours deux1
s, qui, lorsqu'on les additionne entraînera2
. La représentation binaire de deux10
, nous portons la1
à la colonne suivante, et de mettre un0
le résultat dans la première colonne. Toutes les autres colonnes de gauche ont qu'une seule ligne avec un1
, de sorte que le1
reportée de l'exercice précédent de la colonne sera de nouveau ajouter jusqu'à2
, qui va alors effectuer plus de... Ce processus se répète jusqu'à ce que nous obtenons à la colonne la plus à gauche, où l'1
être reporté a nulle part où aller, donc il déborde et se perd, et nous nous retrouvons avec0
s partout.Ce système est appelé Complément de 2. Vous pouvez en lire plus à ce sujet ici:
Complément de 2 Représentation des Entiers Signés.
Maintenant que le cours intensif de 2 effectif de plus, vous remarquerez que
-1
est le seul nombre dont la représentation binaire est1
's partout.À l'aide de la
~
not au niveau du bit opérateur, tous les bits d'un nombre donné sont inversées. La seule façon d'obtenir0
de retour à partir de l'inversion de tous les bits est si nous avons commencé avec1
's partout.Donc, tout cela est un travail de longue haleine manière de dire que
~n
ne retour0
sin
est-1
.!== -1
de toutes les façons imaginables? N'est pas explicite la logique booléenne plus approprié que de façon implicite à l'aide de la falsey-ness de zéro?-1
vérifier ma réponse.>=0
qui a la plus détendue état (lorsque la documentation ne dit que la valeur renvoyée est négative (ce qui peut être!==-1
)~-1 == false
n'est pas portable.~foo.indexOf(bar)
raccourci est un très commune chemin pour écrirefoo.contains(bar)
, de la même manière quefoo || bar
est une commune de la forme abrégée defoo ? foo : bar
00000000000000000000000000000001 + 11111111111111111111111111111111 = 100000000000000000000000000000000 and not 000000000000000000000000000000000 notice the first digit
a || b
en place dea ? a : b
). Depuis cette tilde hack est assez bien connu et utilisé, je ne pense pas que vous aurez à "s'arracher les cheveux" sur elle. Je comprends que c'est une question d'opinion, donc si vous n'aimez pas, ne l'utilisez pas; c'est pourquoi j'ai inclus l'autre méthode dans ma réponse.!= -1
.>=0
, et ajouté un gros note à côté de la tilde solution. C'est la dernière que j'ai à dire à ce sujet.indexOf
retourne-1
pour le manque de présence et b) que la~
opérateur, et/ou ne peuvent pas comprendre ce~[...].indexOf(...)
n' lors de la première lecture, puis sur ils ne sont pas JavaScript experts.~
"non", ce qui provoque ce raccourci pour être totalement confus pour moiif ( x == 'a' ||= 'b' ||= 'c')
. ce serait tellement logique. Et, de même, d'avoir et de = l'habitude de mal non plus comme&&=
.!== -1
. J'espère ne jamais avoir à voir votre code n'importe où.~
, pour ajouter de la complexité. +1 pour>= 0
, il est trivial et tout le monde comprendra.indexOf
sont IE<9 et les premières versions de Firefox. À mon humble avis, vous devriez avoir un polyfill pour cela de toute façon.Vous pouvez utiliser l'instruction switch avec l'automne thru:
||
) sur Chrome. Voir jsperf.com/if-statements-test-techsinL'utilisation de la Science: vous devez faire ce que idfah dit et ce pour le plus rapide tandis que la vitesse de garder le code court:
C'EST plus RAPIDE QUE
~
Méthodehttp://jsperf.com/if-statements-test-techsin
(En haut à définir: Chrome, bas: Firefox)
Conclusion :
Si possibilités sont quelques et vous savez que certains d'entre eux sont plus susceptibles de se produire que vous obtenir le maximum de performance et de
if ||
,switch fall through
, etif(obj[keyval])
.Si possibilités sont de nombreux, et quiconque d'entre eux pourrait être la plupart survenant, en d'autres termes, vous ne pouvez pas le savoir lequel est le plus susceptible de se produire que vous obtenez la plupart de la performance de l'objet de recherche
if(obj[keyval])
etregex
si cela correspond.http://jsperf.com/if-statements-test-techsin/12
je vais mettre à jour si quelque chose de nouveau arrive.
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. Avoir du plaisir.switch or if
n'avez pas à continuer.Si vous comparez à cordes et il y a un patron, pensez à utiliser des expressions régulières.
Sinon, je le soupçonne d'essayer de raccourcir ce sera juste dissimuler votre code. Envisager de simplement envelopper les lignes pour faire joli.
(test.type == 'itemf' && foo.mode == 'detailed')
)À l'aide d'un objet comme un tableau associatif est une chose assez commune, mais depuis que JavaScript n'est pas un natif, vous pouvez utiliser des objets comme pas cher sets.
if
instruction conditionnelle prend 78 caractères si vous supprimez tous les espaces. La Mine dure 54 si vous l'écrire comme ceci:test.type in {"itema":1,"itemb":1,"itemc":1,"itemd":1}
. Fondamentalement, son utilise quatre caractères pour tous les deux de la mine utiliser pour chaque touche supplémentaire.ou si les articles ne sont pas uniformes, puis:
D'excellentes réponses, mais vous pourriez faire le code beaucoup plus lisible en l'enveloppant d'un d'entre eux en fonction.
C'est complexe dans le cas de la déclaration, lorsque vous (ou quelqu'un d'autre) lire le code dans un ans de temps, vous serez la numérisation à travers pour trouver la section de comprendre ce qui se passe. Une déclaration avec ce niveau de la logique d'entreprise vous fera trébucher quelques secondes pendant que vous travaillez que vous souhaitez tester. Où que ce code, vous permettra de poursuivre la numérisation.
Nom de votre fonction explicite immédiatement évident que vous de tester et de votre code sera plus facile à analyser et à comprendre.
// CheckIfBusinessRuleIsTrue
?Vous pouvez mettre toutes les réponses dans un Javascript Pour Définir et puis il suffit d'appeler
.contains()
sur l'ensemble.Vous avez encore de déclarer tous les le contenu, mais la ligne téléphonique sera plus courte.
Quelque chose comme:
Un de mes façons préférées de l'accomplissement, c'est avec une bibliothèque comme underscore.js...
http://underscorejs.org/#some
contains
est sans doute une meilleure solution quesome
some
est une fonction sur le Tableau prototype dans EC5.une autre façon ou d'une autre manière impressionnante que j'ai trouvé est ce...
bien sûr, comme vous pouvez le voir, prend les choses une étape plus loin et de les rendre facile de suivre la logique.
http://snook.ca/archives/javascript/testing_for_a_v
utilisant des opérateurs tels que ~ && || ((),()) ~~ est bien uniquement si votre code pauses plus tard. Vous ne savez pas par où commencer. Si la lisibilité est GRAND.
si vous devez vous pourriez faire plus court.
et si vous voulez faire l'inverse l'
Il suffit d'utiliser un
switch
déclaration au lieu deif
déclaration:Switch
travaille également plus rapide que la comparaison de beaucoup de conditions à l'intérieur d'unif
Pour de très longues listes de chaînes de caractères, cette idée permettrait d'économiser quelques caractères (ne pas le dire je le recommande dans la vraie vie, mais il devrait fonctionner).
Choisir un personnage que vous connaissez ne pas se produire dans votre test.type, de l'utiliser comme délimiteur, collez-les ensemble dans une longue chaîne et de la recherche:
Si vos cordes arrive d'être limité davantage, vous pouvez omettre les délimiteurs...
...mais vous devez être prudent de faux positifs dans ce cas (par exemple, "embite" pourrait correspondre dans cette version)
Pour des raisons de lisibilité de créer une fonction pour le test (oui, une seule ligne):
ensuite l'appeler:
Je pense qu'il y a 2 objectifs lors de l'écriture de ce genre de condition if.
En tant que tel, parfois, #1 pourrait être le plus rapide, mais je vais prendre le #2 pour un entretien facile plus tard. Selon le scénario, je vais souvent opter pour une variation de Walter réponse.
Pour commencer je avoir un ensemble de fonction disponible dans le cadre de ma bibliothèque existante.
et puis quand je veux exécuter une condition si semblables à la vôtre, je voudrais créer un objet avec une liste de valeurs valides:
Il n'est pas aussi rapide qu'un commutateur/instruction de cas, et un peu plus détaillée que celle de certains autres exemples, mais je reçois souvent des ré-utilisation de l'objet ailleurs dans le code, qui peut être assez pratique.
Se greffer sur l'un des jsperf d'échantillons ci-dessus, j'ai ajouté ce test, et une variation de comparer les vitesses. http://jsperf.com/if-statements-test-techsin/6 La chose la plus intéressante je l'ai noté, c'est que certains test de combos dans Firefox sont beaucoup plus rapide que Chrome.
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 voulez, en fonction, la deuxième section pour arrêter la boucle en cours d'exécution, et la troisième partie à cause de la boucle pour finalement quitter.