For example, something like this:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
Is there a better way to write that? Again, I am not seeking an answer to the exact question above, just an example of when you might have repeated operands in ternary operator expressions...
Code should be readable, so being succinct should not mean being terse whatever the cost - for that you should repost to https://codegolf.stackexchange.com/ - so instead I would recommend using a second local variable named
index
to maximize reading comprehensibility (with minimal runtime cost too, I note):But if you really want to cut this expression down, because you're a cruel sadist to your coworkers or project collaborators, then here are 4 approaches you could use:
1: Temporary variable in a
var
statementYou can use the
var
statement's ability to define (and assign) a second temporary variableindex
when separated with commas:2: Self-executing anonymous function
Another option is an self-executing anonymous function:
3: Comma operator
There is also the infamous "comma operator" which JavaScript supports, which is also present in C and C++.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
You can use it to introduce side-effects, in this case by reassigning to
value
:This works because
var value
is interpreted first (as it's a statement), and then the left-most, inner-mostvalue
assignment, and then the right-hand of the comma operator, and then the ternary operator - all legal JavaScript.4: Re-assign in a subexpression
Commentator @IllusiveBrian pointed out that the use of the comma-operator (in the previous example) is unneeded if the assignment to
value
is used as a parenthesized subexpression:Note that the use of negatives in logical expressions can be harder for humans to follow - so all of the above examples can be simplified for reading by changing
idx !== -1 ? x : y
toidx == -1 ? y : x
:I like @slebetman's answer. The comment under it express concern about the variable being in an "intermediate state". if this is a big concern for you then I suggest encapsulating it in a function:
Then just call
You could do more generic functions if you have uses for them in other places, but don't over-engineer if it's a very specific case.
But to be honest I would just do as @slebetman unless I needed to re-use from several places.
There are two ways I can see of looking at your question: you either want to reduce line length, or you specifically want to avoid repeating a variable in a ternary. The first is trivial (and many other users have posted examples):
can be (and should be, given the function calls) shortened like so:
If you are looking for a more generic solution that prevents the repetition of a variable in a ternary, like so:
where
foo
only appears once. Discarding solutions of the form:as technically correct but missing the point, then you are out of luck. There are operators, functions, and methods that possesses the terse syntax you seek, but such constructs, by definition, aren't ternary operators.
Examples:
javascript, using
||
to return the RHS when the LHS isfalsey
:Given the example code at Question it is not clear how it would be determined that
3
is or is not set at index0
ofsomeArray
.-1
returned from.indexOf()
would be valuable in this instance, for the purpose of excluding a presumed non-match which could be a match.If
3
is not included in array,-1
will be returned. We can add1
to result of.indexOf()
to evaluate asfalse
for result being-1
, where followed by||
OR
operator and0
. Whenvalue
is referenced, subtract1
to get index of element of array or-1
.Which leads back to simply using
.indexOf()
and checking for-1
at anif
condition. Or, definingvalue
asundefined
to avoid possible confusion as to actual result of evaluated condition relating to original reference.For this particular case, you could use short-circuiting with the logical
||
operator. As0
is considered falsy, you can+1
to your index, thus, ifindex+1
is0
then you'll get the right-hand side of the return as your result, otherwise, you'll get yourindex+1
. You can then-1
from this result to get your index:EDIT: Here it is, the proposal for Nullary-coalescing now in JavaScript!
Use
||
const result = a ? a : 'fallback value';
is equivalent to
const result = a || 'fallback value';
If casting
a
toBoolean
returnsfalse
,result
will be assigned'fallback value'
, otherwise the value ofa
.Be aware of the edge case
a === 0
, which casts tofalse
andresult
will (incorrectly) take'fallback value'
. Use tricks like this at your own risk.PS. Languages such as Swift have nil-coalescing operator (
??
), which serves similar purpose. For instance, in Swift you would writeresult = a ?? "fallback value"
which is pretty close to JavaScript'sconst result = a || 'fallback value';