Par exemple, quelque chose comme ceci:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
Y a-t-il une meilleure façon d'écrire cela? Encore une fois, je ne cherche pas une réponse à la question exacte ci-dessus, juste un exemple de cas où vous pourriez avoir répété des opérandes dans des expressions d'opérateurs ternaires ...
javascript
conditional-operator
user1354934
la source
la source
if
and not anif/else
just an example of when you might have repeated things in the ternary
ne répétez pas les expressions calculées. C'est à cela que servent les variables.3
n'est pas à l'index0
desomeArray
?Math.max(someArray.indexOf(3), 0)
place?Réponses:
Personnellement, je trouve que la meilleure façon de faire est toujours la bonne vieille
if
déclaration:la source
if
instruction à la place d'un ternaire. Les instructions ternaires sont encore fréquemment utiles pour effectuer un choix dans le cadre d'une expression.value
après la première ligne est intermédiaire. Il ne contient pas la valeur correcte qui est ensuite fixée sur la ligne suivante et est donc un intermédiaire. Ce n'est qu'après laif
conclusion de l' instruction quevalue
contient la valeur correcte. Le ternaire dans l'OP est une meilleure solution que cela car il n'entre jamais dans un état intermédiaire.value
qu'ici est techniquement muté, ce que j'essaye d'éviter.Le code doit être lisible, donc être succinct ne doit pas signifier être laconique quel que soit le coût - pour cela, vous devez republier sur https://codegolf.stackexchange.com/ - donc à la place, je recommanderais d'utiliser une deuxième variable locale nommée
index
pour maximiser la compréhension de la lecture ( avec un coût d'exécution minimal aussi, je note):Mais si vous voulez vraiment réduire cette expression, parce que vous êtes un sadique cruel envers vos collègues ou collaborateurs de projet, alors voici 4 approches que vous pouvez utiliser:
1: variable temporaire dans une
var
instructionVous pouvez utiliser la
var
capacité de l' instruction pour définir (et affecter) une deuxième variable temporaireindex
lorsqu'elle est séparée par des virgules:2: Fonction anonyme auto-exécutable
Une autre option est une fonction anonyme auto-exécutable:
3: opérateur virgule
Il existe également le tristement célèbre "opérateur virgule" pris en charge par JavaScript, qui est également présent en C et C ++.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
Vous pouvez l'utiliser pour introduire des effets secondaires, dans ce cas en le réaffectant à
value
:Cela fonctionne car il
var value
est interprété en premier (car il s'agit d'une instruction), puis l'value
affectation la plus à gauche, la plus intérieure , puis la main droite de l'opérateur virgule, puis l'opérateur ternaire - tout du JavaScript légal.4: réassigner dans une sous-expression
Le commentateur @IllusiveBrian a souligné que l'utilisation de l'opérateur virgule (dans l'exemple précédent) est inutile si l'assignation à
value
est utilisée comme sous-expression entre parenthèses:Notez que l'utilisation de négatifs dans les expressions logiques peut être plus difficile à suivre pour les humains - donc tous les exemples ci-dessus peuvent être simplifiés pour la lecture en passant
idx !== -1 ? x : y
àidx == -1 ? y : x
:la source
indefOf
)var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
lieu d'utiliser une virgule.var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
car ce n'est qu'un paramètre.Pour les nombres
Vous pouvez utiliser la
Math.max()
fonction.Cela gardera les limites du résultat du
0
jusqu'au premier résultat plus grandes que0
si tel était le cas. Et si le résultat deindexOf
est-1
il renverra 0 comme supérieur à-1
.Pour les valeurs booléennes et booléennes-y
Pour JS, il n'y a pas de règle générale AFAIK spécialement parce que les valeurs fausses sont évaluées.
Mais si quelque chose peut vous aider la plupart du temps, c'est l'opérateur or (
||
):Vous devez être très prudent avec cela, car dans votre premier exemple,
indexOf
peut retourner0
et si vous l'évaluez,0 || -1
il retournera-1
parce que0
c'est une valeur erronée .la source
3
ou"y"
n'est pas à l'index0
desomeArray
?Math.max
exemple?indexOf
renvoie l'index de l'élément et si l'élément n'est pas trouvé renvoie -1 donc vous avez une chance d'obtenir un nombre de -1 à la longueur de la chaîne, alors avecMath.max
vous définissez simplement les limites de 0 à la longueur pour supprimer la chance pour retourner un -1,0
de l'élément correspondant dans le tableau, ou0
fixé àMath.max()
; ou à l'opérateur conditionnel à OP. Considérezvar value = Math.max( ["y"].indexOf("y"), 0 )
. Comment déterminez-vous lequel0
est retourné?0
transmis àMath.max()
appel, ou0
reflétant l'index de l'"y"
intérieur du tableau?Pas vraiment, utilisez simplement une autre variable.
Votre exemple se généralise à quelque chose comme ça.
Vous testez une valeur calculée, puis affectez cette valeur à une variable si elle passe un prédicat. La manière d'éviter de recalculer la valeur calculée est évidente: utilisez une variable pour stocker le résultat.
Je comprends ce que vous voulez dire - il semble qu'il devrait y avoir un moyen de faire cela qui semble un peu plus propre. Mais je pense que c'est la meilleure façon (idiomatique) de le faire. Si vous répétiez beaucoup ce modèle dans votre code pour une raison quelconque, vous pourriez écrire une petite fonction d'aide:
la source
EDIT: Le voici, la proposition de Nullary-coalescing maintenant en JavaScript!
Utilisation
||
const result = a ? a : 'fallback value';
est équivalent à
const result = a || 'fallback value';
Si la conversion
a
enBoolean
retournefalse
,result
sera attribuée'fallback value'
, sinon la valeur dea
.Soyez conscient du cas de bord
a === 0
, qui lancefalse
etresult
prendra (incorrectement)'fallback value'
. Utilisez des trucs comme celui-ci à vos propres risques.PS. Les langages tels que Swift ont l' opérateur nil-coalescing (
??
), qui a un objectif similaire. Par exemple, dans Swift, vous écririezresult = a ?? "fallback value"
ce qui est assez proche de JavaScriptconst result = a || 'fallback value';
la source
indexOf()
ne peut pas être utilisée dans ce modèle.||
fonctionne JavaScript? Si je vous comprends bien, cela fonctionne différemment de nombreux autres langages primaires (je pense principalement à C et à ses descendants [C ++, Java, etc.]) Même si c'est vraiment ainsi que||
fonctionne en JavaScript, je déconseille d'utiliser des trucs comme celui-ci qui obligent les responsables à connaître les particularités du langage. Bien que cette astuce soit cool, je la considérerais comme une mauvaise pratique.-1
. Encore une fois, je ne peux pas parler de JavaScript et de ses bizarreries, mais ce-1
serait généralement une valeur vraie, pas une fausse, et donc votre réponse ne fonctionnerait pas dans le cas de la question et certainement pas dans le cas général, mais plutôt dans un cas spécifique ( mais assez commun) sous-cas.Utilisez un refactoring de variable d'extrait :
C'est encore mieux avec
const
au lieu devar
. Vous pouvez également faire une extraction supplémentaire:Dans la pratique, utiliser des noms plus significatifs que
index
,condition
etvalue
.la source
Vous recherchez probablement un opérateur de fusion. Heureusement, nous pouvons tirer parti du
Array
prototype pour en créer un:Cela pourrait être généralisé à votre cas, en ajoutant un paramètre à la fonction:
la source
for (let x in ['b','c']) console.log(x);
gravures0
,1
,"coalesce"
.Personnellement, je préfère deux variantes:
Pure si, comme @slebetman l'a suggéré
Fonction séparée, qui remplace la valeur invalide par une valeur par défaut, comme dans cet exemple:
la source
J'aime la réponse de @ slebetman. Le commentaire sous celui-ci exprime une inquiétude quant au fait que la variable se trouve dans un "état intermédiaire". si c'est un gros problème pour vous, je vous suggère de l'encapsuler dans une fonction:
Alors appelez simplement
Vous pouvez faire des fonctions plus génériques si vous en avez des utilisations ailleurs, mais ne sur-ingénierie pas si c'est un cas très spécifique.
Mais pour être honnête, je ferais simplement comme @slebetman à moins d'avoir besoin de réutiliser à plusieurs endroits.
la source
Je peux voir deux façons de regarder votre question: vous voulez soit réduire la longueur de la ligne, soit vous voulez spécifiquement éviter de répéter une variable dans un ternaire. Le premier est trivial (et de nombreux autres utilisateurs ont publié des exemples):
peut être (et devrait être, étant donné les appels de fonction) raccourcis comme ceci:
Si vous cherchez une solution plus générique qui empêche la répétition d'une variable dans un ternaire, comme ceci:
où
foo
n'apparaît qu'une seule fois. Rejeter les solutions du formulaire:comme techniquement correct mais manquant le point, alors vous n'avez pas de chance. Il existe des opérateurs, des fonctions et des méthodes qui possèdent la syntaxe laconique que vous recherchez, mais ces constructions, par définition, ne sont pas des opérateurs ternaires .
Exemples:
javascript, en utilisant
||
pour renvoyer le RHS lorsque le LHS estfalsey
:la source
Utilisez une fonction d'assistance:
Maintenant, votre code est très lisible et il n'y a pas de répétition.
La hiérarchie des préoccupations de codage est:
Toutes les réponses sur la page semblent jusqu'à présent être correctes, mais je pense que ma version est la plus claire, ce qui est plus important que la concision. Si vous ne comptez pas la fonction d'assistance, car elle peut être réutilisée, elle est également la plus concise. La suggestion quelque peu similaire d'utiliser une fonction d'assistance utilise malheureusement un lambda qui, pour moi, obscurcit simplement ce qu'il fait. Une fonction plus simple avec un objectif qui ne prend pas de lambda, juste des valeurs, est pour moi bien meilleure.
PS Si vous aimez la syntaxe ES6:
la source
translateValueIfEqual
que je pensais plus descriptif, mais je l'ai changé après que quelqu'un ait pensé qu'il était trop long. Tout comme laNz
fonction dans Access, si vous la connaissez, vous la connaissez, et si vous ne le faites pas, vous ne le savez pas. Dans les IDE modernes, vous pouvez simplement appuyer sur une touche pour accéder à la définition. Et le repli serait la variable intermédiaire. Je ne vois pas vraiment de gros inconvénient ici.Je pense que l'
||
opérateur peut être adapté pourindexOf
:La valeur retournée est décalée de 1 vers le haut, faisant 0 de -1, ce qui est faux et est donc remplacée par la seconde 1. Puis elle est décalée vers l'arrière.
Cependant, gardez à l'esprit que la lisibilité est supérieure à éviter les répétitions.
la source
Il s'agit d'une solution simple avec NOT au niveau du bit et une valeur par défaut
-1
dont les résultats ultérieurs à zéro.Cela fonctionne essentiellement avec un double NOT au niveau du bit, qui renvoie la valeur d'origine ou une valeur par défaut, qui après l'application du NOT au niveau du bit, renvoie zéro.
Jetons un coup d'œil à la table de vérité:
la source
Vous pouvez utiliser la réaffectation:
&&
opérateur pour la réaffectation, car si la première condition est fausse, la deuxième expression ne sera pas évaluéeEx.
Afficher l'extrait de code
la source
someArray.indexOf
n'est exécutée qu'une seule foisvalue
.-1
et0
; sinon cemax()
serait la meilleure optionAgain, not seeking an answer to the exact question above
, ce qui laisse la question à l'interprétation;)Compte tenu de l'exemple de code à Question, il n'est pas clair comment déterminer s'il
3
est défini ou non à l'index0
desomeArray
.-1
renvoyé de.indexOf()
serait précieux dans ce cas, dans le but d'exclure une non-correspondance présumée qui pourrait être une correspondance.Si
3
n'est pas inclus dans le tableau,-1
sera retourné. Nous pouvons ajouter1
au résultat de.indexOf()
pour évaluer commefalse
résultat étant-1
, où suivi par l'||
OR
opérateur et0
. Quandvalue
est référencé, soustraire1
pour obtenir l'index de l'élément du tableau ou-1
.Ce qui revient à simplement utiliser
.indexOf()
et vérifier-1
uneif
condition. Ou, définirvalue
commeundefined
pour éviter toute confusion quant à la suite de l' état réel évalué relatif à la référence originale.la source
Un ternaire est comme un if-else, si vous n'avez pas besoin de l'autre partie, pourquoi pas juste un if à la place ...
la source
Dans ce cas particulier, vous pouvez utiliser un court-circuit avec l'
||
opérateur logique . Comme cela0
est considéré comme faux, vous pouvez ajouter1
à votre index, donc, siindex+1
c'est le cas,0
vous obtiendrez le côté droit de la logique - ou comme résultat, sinon, vous obtiendrez votreindex+1
. Comme votre résultat souhaité est compensé par1
, vous pouvez ensuite en soustraire1
pour obtenir votre index:la source