Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to nested ternary operator in JS

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.

like image 520
dthree Avatar asked Aug 29 '15 18:08

dthree


People also ask

What can I use instead of nested ternary?

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.

Why is there no nested ternary?

Nesting ternary expressions can make code more difficult to understand.

Can we use nested ternary operator in JavaScript?

You can nest one ternary operator as an expression inside another ternary operator to work as a Nested ternary operator in JavaScript.


2 Answers

Your alternatives here are basically:

  1. That if/else you don't want to do
  2. A switch 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? :-)

like image 184
T.J. Crowder Avatar answered Oct 05 '22 14:10

T.J. Crowder


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' ; 
like image 20
Andrey Mikhaylov - lolmaus Avatar answered Oct 05 '22 12:10

Andrey Mikhaylov - lolmaus