最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to put a switch statement inside of a Conditional (ternary)? - Stack Overflow

programmeradmin0浏览0评论

I'm really new to using Conditional (ternary) operator. Is it possible to put a switch statement in this operator?

This is what i tried:

function find(cn, romanNum) {
        if (cn >= 1 && cn <= 3) {
          return repeatString(romanNum[2], cn);
       }
        cn > 5 && cn < 9 ? return romanNum[1] + repeatString(romanNum[2], cn - 5) : switch(cn) {
            case 4:
            return romanNum[2] + romanNum[1];
            case 5: 
            return romanNum[1];
            case 9:
            return romanNum[2] + romanNum[0];
    }
}

I'm doing something wrong i know, but what is it? Everyone is new to something at some point in time.


Error:

  • Expected a identifier and instead saw 'return'.
  • Expected ':' and instead saw 'romanNum'.
  • Missing semicolon.
  • Expected '}' to match '{' from line 58 and instead saw ':'

This is the right es5 code:

function find(cn, romanNum) {
        if (cn >= 1 && cn <= 3) {
            return repeatString(romanNum[2], cn);
        } else if (cn == 4) {
            return romanNum[2] + romanNum[1];
        } else if (cn == 5) {
            return romanNum[1];
        } else if (cn == 9) {
            return romanNum[2] + romanNum[0];
        }
        if (cn > 5 && cn < 9) {
            return romanNum[1] + repeatString(romanNum[2], cn - 5);
        }
    }

Help?

I'm really new to using Conditional (ternary) operator. Is it possible to put a switch statement in this operator?

This is what i tried:

function find(cn, romanNum) {
        if (cn >= 1 && cn <= 3) {
          return repeatString(romanNum[2], cn);
       }
        cn > 5 && cn < 9 ? return romanNum[1] + repeatString(romanNum[2], cn - 5) : switch(cn) {
            case 4:
            return romanNum[2] + romanNum[1];
            case 5: 
            return romanNum[1];
            case 9:
            return romanNum[2] + romanNum[0];
    }
}

I'm doing something wrong i know, but what is it? Everyone is new to something at some point in time.


Error:

  • Expected a identifier and instead saw 'return'.
  • Expected ':' and instead saw 'romanNum'.
  • Missing semicolon.
  • Expected '}' to match '{' from line 58 and instead saw ':'

This is the right es5 code:

function find(cn, romanNum) {
        if (cn >= 1 && cn <= 3) {
            return repeatString(romanNum[2], cn);
        } else if (cn == 4) {
            return romanNum[2] + romanNum[1];
        } else if (cn == 5) {
            return romanNum[1];
        } else if (cn == 9) {
            return romanNum[2] + romanNum[0];
        }
        if (cn > 5 && cn < 9) {
            return romanNum[1] + repeatString(romanNum[2], cn - 5);
        }
    }

Help?

Share Improve this question edited Nov 25, 2017 at 16:48 Leed asked Nov 25, 2017 at 16:21 LeedLeed 3033 gold badges5 silver badges12 bronze badges 13
  • 1 No, that is not possible. Since ?: is an operator, its operands have to be expressions, but switch is a statement – not an expression. (Same with return.) You might have been hoping for github.com/tc39/proposal-pattern-matching? – Ry- Commented Nov 25, 2017 at 16:22
  • 3 Don't force use of a ternary here. Ternarys are exclusively meant to evaluate to one of two values. Your use here is abuse. Just us an if. – Carcigenicate Commented Nov 25, 2017 at 16:23
  • 6 Why would you want to write such cryptic code anyway? – nicholaswmin Commented Nov 25, 2017 at 16:23
  • 2 smaller ≠ simplified – Ry- Commented Nov 25, 2017 at 16:24
  • 1 @Leed Don't sacrifice readability to make code smaller. Just use an if. – Carcigenicate Commented Nov 25, 2017 at 16:25
 |  Show 8 more comments

4 Answers 4

Reset to default 7

tl;dr: kind of, but you shouldn't do it since it is not that readable.
Always keep code short an simple but verbose.

Long answer: You could wrap your switch inside an immediately invoked anonymous function.

const a = 20;
const condition = a > 100;
const result = condition ? true : ( () => {
  switch ( a ) {
    case 11: return 22;
    case 20: return 21;
    default: return 100;
  }
} )();

console.log( result );

But not only is this more complex but also harder to read.

It is better to use a verbose coding style. In your case something like this would be cleaner and more readable:

function test( a ) {
  const condition = a > 100;

  if ( condition ) {
    return true;
  }
  
  switch ( a ) {
    case 20: return 21;
    default: return 100;
  }
}

console.log( test( 20 ) );

You can use an IIFE:

return condition
  ? (() => {
      switch (val) {
        case x: return a;
        case y: return b;
        default: return c;
      }
    })()
  : other;

however this is horribly unreadable and not even shorter than the simple if statement.


That said, there is a much better choice than switch for looking up values: a lookup table! Just use an object, array or Map and use your cn as the property name.

const table = {
  1: repeatString(romanNum[2], 1),
  2: repeatString(romanNum[2], 2),
  3: repeatString(romanNum[2], 3),
  4: romanNum[2] + romanNum[1],
  5: romanNum[1],
  6: romanNum[1] + repeatString(romanNum[2], 1),
  7: romanNum[1] + repeatString(romanNum[2], 2),
  8: romanNum[1] + repeatString(romanNum[2], 3),
  9: romanNum[2] + romanNum[0]
};
function find(cn) {
  return table[cn];
}

// using an array similar to the object above:
table = [
  ...Array.from({length: 4}, (_, i) => repeatString(romanNum[2], i))
  romanNum[2] + romanNum[1],
  ...Array.from({length: 4}, (_, i) => romanNum[1] +  repeatString(romanNum[2], i)),
  romanNum[2] + romanNum[0]
];

You could use a nested ternary whith an object as replacement for the select structure.

function find(cn, romanNum) {
    return cn >= 1 && cn <= 3
        ? repeatString(romanNum[2], cn)
        : cn > 5 && cn < 9
            ? romanNum[1] + repeatString(romanNum[2], cn - 5)
            : {
                4: romanNum[2] + romanNum[1],
                5: romanNum[1],
                9: romanNum[2] + romanNum[0]
            }[cn];
}

A step further, you could omit the second ternary and use the first condition as default value for the result of non existent property of the object.

function find(cn, romanNum) {
    return cn >= 1 && cn <= 3
        ? repeatString(romanNum[2], cn)
        : {
            4: romanNum[2] + romanNum[1],
            5: romanNum[1],
            9: romanNum[2] + romanNum[0]
        }[cn] || romanNum[1] + repeatString(romanNum[2], cn - 5);
}
  1. U cant use the return like this just a small example to show how to return in normal ternary operator

    function find(cn, romanNum) {
        if (cn >= 1 && cn <= 3) {
         return 2;
       }
    
      return  (cn > 5 && cn < 9) ? ( romanNum[1] + 2, cn - 5) : 3
    

    }

  2. No its not possible to use switch statement in ternary operator because switch is a statement not a condition or expression

  3. Better use if -else

  4. If you want to stick to ternary then make the changes like

function find(cn, romanNum) {
        if (cn >= 1 && cn <= 3) {
          return repeatString(romanNum[2], cn);
       }
      return  cn > 5 && cn < 9 ?  romanNum[1] + repeatString(romanNum[2], cn - 5) : (cn===4 ?   romanNum[2] + romanNum[1]:
          (cn==5 ? romanNum[1] : romanNum[2] + romanNum[0]))
}

console.log(find(2,[1,2,3,4]))

Though I wont prefer nested ternary operator as it hinders the readability of the code .

发布评论

评论列表(0)

  1. 暂无评论