I personally love ternary operators, and in my humble opinion, they make complicated expressions very easy to digest. Take this one:
const word = (distance === 0) ? 'a' : (distance === 1 && diff > 3) ? 'b' : (distance === 2 && diff > 5 && key.length > 5) ? 'c' : 'd';
However in our project's ESLINT rules nested ternary operators are forbidden, so I have to get rid of the above.
I'm trying to find out alternatives to this approach. I really don't want to turn it into a huge if / else statement, but don't know if there's any other options.
If you are looking to use const with a nested ternary expression, you can replace the ternary with a function expression. Show activity on this post.
Nesting ternary expressions can make code more difficult to understand.
You can nest one ternary operator as an expression inside another ternary operator to work as a Nested ternary operator in JavaScript.
Your alternatives here are basically:
if
/else
you don't want to doswitch
combined with if
/else
I tried to come up with a reasonable lookup map option, but it got unreasonable fairly quickly.
I'd go for #1, it's not that big:
if (res.distance == 0) { word = 'a'; } else if (res.distance == 1 && res.difference > 3) { word = 'b'; } else if (res.distance == 2 && res.difference > 5 && String(res.key).length > 5) { word = 'c'; } else { word = 'd'; }
If all the braces and vertical size bother you, without them it's almost as concise as the conditional operator version:
if (res.distance == 0) word = 'a'; else if (res.distance == 1 && res.difference > 3) word = 'b'; else if (res.distance == 2 && res.difference > 5 && String(res.key).length > 5) word = 'c'; else word = 'd';
(I'm not advocating that, I never advocate leaving off braces or putting the statement following an if
on the same line, but others have different style perspectives.)
#2 is, to my mind, more clunky but that's probably more a style comment than anything else:
word = 'd'; switch (res.distance) { case 0: word = 'a'; break; case 1: if (res.difference > 3) { word = 'b'; } break; case 2: if (res.difference > 5 && String(res.key).length > 5) { word = 'c'; } break; }
And finally, and I am not advocating this, you can take advantage of the fact that JavaScript's switch
is unusual in the B-syntax language family: The case
statements can be expressions, and are matched against the switch value in source code order:
switch (true) { case res.distance == 0: word = 'a'; break; case res.distance == 1 && res.difference > 3: word = 'b'; break; case res.distance == 2 && res.difference > 5 && String(res.key).length > 5: word = 'c'; break; default: word = 'd'; break; }
How ugly is that? :-)
To my taste, a carefully structured nested ternary beats all those messy ifs and switches:
const isFoo = res.distance === 0; const isBar = res.distance === 1 && res.difference > 3; const isBaz = res.distance === 2 && res.difference > 5 && String(res.key).length > 5; const word = isFoo ? 'a' : isBar ? 'b' : isBaz ? 'c' : 'd' ;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With