【问题标题】:How do I turn these If else statements into Switch statements如何将这些 If else 语句转换为 Switch 语句
【发布时间】:2020-05-25 05:10:04
【问题描述】:

所以我有一个简单的功能来查看复选框中选中的内容,然后吐出价格。我试图做到这一点,所以我有所有可能的组合作为“如果”语句,所以无论用户选择什么,都会弹出正确的价格。我只是想知道如何将这段代码转换为 switch 语句以使其高效。如果还有什么其他效率低下的问题我应该解决,我希望得到反馈,这是我在学校项目中使用 JS 的第一周。

    <!DOCTYPE html>
<html>

<head>
<script>
function testFunc() {
  cost = 0;
  var isOne = document.getElementById('Maui').checked;
  var isTwo = document.getElementById('Oahu').checked;
  var isThree = document.getElementById('Hawaii').checked;


  if(isOne) {
    cost += 1350
  }
  if(isOne && isTwo) {
    cost = 1850
  }
  if(isOne && isTwo && IsThree) {
    cost = 2100
  }
  else{
    cost = 1350
}
  if(isTwo){
    cost += 0
  }

  document.getElementById('cost').innerHTML = cost;
}

</script>
</head>

<body>

<h2>Chose Islands For Package/h2>

<form>
  <input type="checkbox" id="Maui">

  <label>Maui</label><br>

  <input type="checkbox" id="Oahu">

  <label>Oahu</label><br>

  <input type="checkbox" id="Hawaii">

  <label>Hawaii</label><br>


</form>

 <button onclick="testFunc()">Price </button>

 <p id="cost"> </p>

</body>
</html>

编辑:对不起,我想我没有澄清,去一个岛的费用是 1350,不管是哪个岛。我认为我想要做的事情对于简单的 JS 代码来说太复杂了。例如,如果我选择夏威夷,它将是 1350,如果我选择两个岛屿,它将是 1850,但如果它只有一个岛,例如 Ohau,它将再次是 1350。我正在考虑为每个可能的变化做数组和/或编写 if/else 语句,因为 switch 语句似乎不是最好的选择。

【问题讨论】:

  • 因为您要比较多个变量,所以您应该坚持使用 if/else 而不是 switch。
  • 哟,可能,考虑一些新的答案作为回答如何执行实际 switch 语句的问题的接受的答案,因为当前接受的答案忽略了这个问题,如果你发现它们更有帮助(从不害怕将接受的答案从一个更改为一个更好的答案!:))
  • 我也可以谦虚地推荐一个可能已经出现的新答案*.com/a/61996412/2016831,您可能觉得它很有用

标签: javascript if-statement switch-statement


【解决方案1】:

switch 语句用于检查一个值(或变量)是否等于其他值子集中的任何一个。

例如,如果var string的值有一个case等于foobar等。在这种情况下有多个变量被检查,所以switch 语句的简单含义不适合。

然而,每个布尔值本质上都是真或假,因此您可以改为切换另一个布尔变量的大小写,以检查它是否等于其他任何一个。

还请记住,对于 switch 语句,函数 switch 会准确检查输入其中的参数,类似于===,每种情况。

因此,与其检查一个变量是否为许多变量的布尔值,就像在if 语句中那样,您可以做相反的事情,并根据输入到switch 的参数检查许多变量,即“真”(所有布尔值的结果)。

请记住,在检查布尔值时,您不能使用 switch(1),因为在 JavaScript 中 1 !== true,即使 1 == 2(3 个等号之间的差异(包括 ! 和 2,有关更多信息差异,因此,您可以将 switch 案例与什么进行比较,请参阅Which equals operator (== vs ===) should be used in JavaScript comparisons?)。

所以你可以这样做, 例如:

<!DOCTYPE html>
<html>

<head>
<script>
function testFunc() {
  cost = 0;
  var isOne = document.getElementById('Maui').checked;
  var isTwo = document.getElementById('Oahu').checked;
  var isThree = document.getElementById('Hawaii').checked;


  switch(true) {
    case isOne && isTwo && isThree: 
      cost = 2100;
      break;
    case isOne && isTwo:
      cost = 1850;
      break;
    case isTwo && isThree:
      cost = (2100 - 1350);
      break;
    case isOne: 
      cost = 1350;
      break;
    case isTwo:
      cost = (1850 - 1350 /*based on earlier*/)
      break;
    case isThree:
      cost = 2100 - 1850 //based on earlier
      break;
    default: cost = 0
  }
  

  document.getElementById('cost').innerHTML = cost;
}

</script>
</head>

<body>

<h2>Chose Islands For Package/h2>

<form>
  <input type="checkbox" id="Maui">

  <label>Maui</label><br>

  <input type="checkbox" id="Oahu">

  <label>Oahu</label><br>

  <input type="checkbox" id="Hawaii">

  <label>Hawaii</label><br>


</form>

 <button onclick="testFunc()">Price </button>

 <p id="cost"> </p>

</body>
</html>

还要注意检查多个值的情况如何在switch/case 中排在第一位,因为它的工作方式是检查每个情况,并返回第一个为真的情况。

我还添加了一个以前没有的额外检查案例,即case isTwo &amp;&amp; isThree

但是顺便说一句,如果你只是想计算每个地方的总价格,更有效的方法是简单地创建一个 map 对象作为名称到价格值,然后遍历所有案例,检查它的价格值,并将其添加到成本中,如下所示:

<!DOCTYPE html>
<html>

<head>
<script>
function testFunc() {
  cost = 0;
  var map = {
    Maui: 1350,
    Oahu: 500,
    Hawaii: 250
  };
  
  Array.apply(0, myForm.elements)
  .forEach(x => {
    if(x.checked) {
      var cur = map[x.id]
      if(cur) cost += cur;
    }
  });

  document.getElementById('cost').innerHTML = cost;
}

</script>
</head>

<body>

<h2>Chose Islands For Package/h2>

<form id=myForm>
  <input type="checkbox" id="Maui">

  <label>Maui</label><br>

  <input type="checkbox" id="Oahu">

  <label>Oahu</label><br>

  <input type="checkbox" id="Hawaii">

  <label>Hawaii</label><br>


</form>

 <button onclick="testFunc()">Price </button>

 <p id="cost"> </p>

</body>
</html>

因为正在执行此操作的当前模型需要 N! 数量的 case 检查,N 代表您拥有的总案例。

因此,例如,如果您有 10 选项可供选择,则必须手动写出 10!3,628,800 个人 case 支票!!!

【讨论】:

  • 修改你的第一段代码后,我得到了我需要的东西,谢谢!我花了一段时间测试了每个人给出的每个答案,但你的似乎一针见血。我只需要修改并添加更多案例即可获得我想要的结果。非常感谢!
  • @AriaGhasemi 很酷,很高兴这一切都解决了,如果有其他问题或需要,请告诉我 :)
【解决方案2】:

我会把你的 testFunc 函数改成这样:

function testFunc() {
    var total = 0;
    var maui = document.getElementById('Maui');
    var oahu = document.getElementById('Oahu');
    var hawaii = document.getElementById('Hawaii');

    total = (maui.checked ? 1350 : 0) + 
            (oahu.checked ? 500 : 0) + 
            (hawaii.checked ? 250 : 0);

    document.getElementById('cost').innerHTML = total;
}

编辑:我没有使用 switch 语句,只是为了提高整体效率。

看看其他答案,包括接受的答案,我认为他们继承了对价格求和的错误,没有毛伊岛 + 夏威夷的情况。

我提供的解决方案适用于任何组合。

【讨论】:

  • 不错的解决方案,虽然它不涉及 switchcase 像问的问题
  • 看到这个效果更好,但我试图解决的问题,我也试图从我标记的答案中解决,去夏威夷岛旅行的费用不是 250,当我选择你的解决方案时Haiwaii,它说成本是 250,但实际上一个岛屿的成本是 1350,我似乎无法弄清楚如何计算。
【解决方案3】:

为什么您认为if and else 语句的这些组合会使您的核心效率低下?我建议你提取一个计算cost的方法,这样代码的意图会更清楚:

function testFunc() {
     var isMaui = document.getElementById('Maui').checked;
     var isOahu = document.getElementById('Oahu').checked;
     var isHawaii = document.getElementById('Hawaii').checked;

     document.getElementById('cost').innerHTML = calculateCost(isMaui, isOahu, isHawaii);
}

function calculateCost(isMaui, isOahu, isHawaii) {
   if(isMaui && isOahu && isHawaii) {
       return 2100;
   } else if (isMaui && isOahu) {
       return 1850;
   } else if (isMaui) {
       return 1350;
   } else {
       return 1350;
   }

}

【讨论】:

  • 啊,这更有意义。我想我没有正确使用代码。这效果更好。谢谢!
  • stil 没有回答如何在 switch case 中进行操作
【解决方案4】:

下面的代码可以做到:

switch(true){
     case isOne:
            cost += 1350;
            break;
     case isOne&&isTwo:
            cost += 1850;
            break;
     case isOne&&isTwo&&isThree:
            cost += 2100;
            break;
     default:
            cost=1350;

}

【讨论】:

  • @bluejayke 如果您在复制和粘贴时遇到语法错误。这是因为在这个例子中SwitchCase 是大写的。他们不应该是。 JavaScript 区分大小写,ClassesConstructor Functions 保存大写字母
  • @UzairAshraf 没有复制和粘贴,重写它,只是没有意识到它正在检查布尔值。例如我有以下switch(1) {case window.test: console.log("testing");break;default:console.log("nothing"))},首先我在没有定义“test”的情况下尝试它,然后得到默认值,然后我也尝试定义test,但仍然得到默认值,然后我意识到它正在检查它,类似于===,所以只好把测试用例改成case !!window.test
  • @UzairAshraf 也是声明 switch(1),在 JS 中不起作用,由于上述原因,它必须是 switch(true),因为在 JS 中 1 !== /*notice the two "="s*/ true
  • 啊,明白了!这是有道理的。
【解决方案5】:

首先,您总是希望使用 var 关键字声明新变量。如果你不创建一个叫做自动全局变量的东西。这可能会在以后使用更大的代码库产生不可预知的错误。

其次,使用 switch case 语句并不是更有效。我建议坚持使用 if/else 语句。此外,如果我正确理解您的代码,如果检查了某些内容,您可能会尝试调整价格。测试每个变量可能会更容易,并且会随着您的使用而增加成本

var cost = 0;
if(isOne) {
 cost += 1350
}
if(isTwo) {
 cost += 1850
}
if(isThree) {
 cost +=2100
}

这样它总是从零开始,如果没有一个条件解析为真,那么成本不会从零开始变化。

希望这会有所帮助!

【讨论】:

  • 这没有回答问题
  • 使用 switch 语句是 Uzair 在效率方面的想法,但他也说要回复我们也会使其高效的内容,就我而言,这个答案很好。