在条件语句(三元运算符)中是否可以使用switch语句?

4

我是一名新手,对于条件(三目)运算符的使用还不熟悉。请问在这个运算符中能否使用switch语句?

我尝试过以下代码:

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];
    }
}

我知道我在做错了什么,但是是什么呢?每个人在某个时候都会遇到新的东西。


错误:

  • 期望一个标识符,而看到的是'return'
  • 期望':',而看到的是'romanNum'
  • 缺少分号。
  • 期望'}'与第58行的'{'匹配,而看到的是':'

这是正确的es5代码:

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?


1
不,这是不可能的。因为 ?: 是一个运算符,它的操作数必须是表达式,但 switch 是一个语句,而不是表达式。(return 同理。)你可能希望参考 https://github.com/tc39/proposal-pattern-matching? - Ry-
3
不要强制使用三元运算符,它只能用于返回两个值中的一个。你在这里的使用是滥用。请使用 if 语句。 - Carcigenicate
6
你为什么要写这样的晦涩代码呢? - nicholaswmin
2
小 ≠ 简化 - Ry-
1
@Leed 不要为了让代码更小而牺牲可读性,只需使用 if 语句即可。 - Carcigenicate
显示剩余8条评论
4个回答

6

tl;dr: 有点像,但你不应该这么做,因为它不够易读。
始终保持代码短小精悍但冗长。

详细回答: 你可以将 switch 包装在立即调用的匿名函数中。

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 );

但这不仅更加复杂,而且更难阅读。

最好使用冗长的编码风格。在您的情况下,类似于以下内容会更加清晰易读:

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

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

console.log( test( 20 ) );


我该如何实现真和假?如果为真,我希望它运行一行代码,否则切换。 - Leed
我在答案末尾更新了一个更易读的代码示例。 - lumio

4

您可以使用立即执行函数(IIFE):

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

然而,这种写法非常难读,并且甚至比简单的“if”语句还要长。
话虽如此,查找值有比“switch”更好的选择:查找表!只需使用对象、数组或Map,并将您的“cn”用作属性名称。
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]
];

1
那么它将遍历表格并根据“cn”的值返回数据? - Leed
它不会穿过表格,而是直接到达表格中的正确位置。 - Bergi
我尝试了一下,但它没有返回正确的结果--> https://repl.it/@John_Nicole/Intermediate-Algorithm-Scripting-Roman-Numeral-Converter (第58行,我暂时放置了一些旧的ES5代码)。 - Leed

2
你可以使用一个嵌套的三元表达式,将对象作为替代 select 结构的方法。
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];
}

更进一步,你可以省略第二个三元运算符,并使用第一个条件作为对象不存在属性的默认值。
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);
}

你的回答是最简短的,谢谢。它也很容易理解。谢谢。同时也感谢其他所有回答的人 :) - Leed

1
  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]))

虽然我不喜欢嵌套三元运算符,因为它会影响代码的可读性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接