【问题标题】:If statement multiple conditionals on one value without repeating value如果在一个值上声明多个条件而不重复值
【发布时间】:2016-01-27 18:29:55
【问题描述】:

我想知道是否有一种方法可以检查同一变量或值的多个条件而不重复该值。

例如,如果我有变量keyCode,并且我想检查它是否大于 102,或小于 48,或介于 65 和 57 之间,或者介于 70 和 97 之间,我必须写这个:

var keyCode = // some value;
if(
    keyCode > 102 ||
    keyCode < 48 ||
    (keyCode > 57 && keyCode < 65) ||
    (keycode > 70 && keyCode < 97)
) {
    // do something
}

如您所见,我在if 条件下写了keyCode 6 次。如果条件更复杂(这个条件简单地排除了所有非十六进制字符),那么它可能会更加重复。

我想知道是否有办法简化这一点。也许是这样的:

if(
    keyCode > 102 || < 48 || (> 57 && < 65) || (> 70 && < 97)
) {
    // do something
}

您可以在其中简单地省略变量名并将许多条件放在单个变量上。就像this question 的反面一样,提问者想知道是否有一种方法可以针对单个条件检查多个变量。

我现在正在用 JS 编写代码,但如果您知道任何其他语言的实现,那将来也可能会有所帮助。我认为这会有一个简单的实现,因为我经常使用它,但我惊讶地发现我根本找不到任何关于这样的语言功能的信息。

【问题讨论】:

  • 条件的目的是比较,对吧?好吧,您正在尝试删除似乎构建速记条件的比较器之一。那不是一回事。它适用于伪代码,但对于 javascript 中的实际实现,它是不行的
  • @FallenReaper 我觉得它应该是“一件事”。我不喜欢凌乱、重复的代码,我希望有一些速记条件或其他比我必须开始的更优雅的解决方案。你有其他的想法吗?
  • 预填充一个数组以用作键代码的查找表以确定其可接受性:if(ok[keyCode])...,其中数组 like [0,0,0,1,1,0,1...]
  • @dandavis 这仅适用于我上面给出的特定情况(具有有限可能性的键码)。这在大多数其他解决方案中都行不通。
  • 不知道你的意思,只有这么多键......你可以使用不同的集合:if(arrArrows[keyCode] || arrPauses[keyCode])

标签: javascript if-statement conditional


【解决方案1】:

我知道的唯一简化方法是创建具有有意义名称的单独函数,例如:

function inRange(value, min, max) {
    return (value > min) && (value < max);
}
function outRange(value, min, max) {
    return (value < min) || (value > max);
}

那么您的情况将如下所示:

if (outRange(keyCode, 48, 102) || inRange(keyCode, 57, 65) || inRange(keyCode, 70, 97) ) {
    ...
}

这更容易理解,因为您看到的是原始意图,而不是不同的 &gt; &lt; 并试图理解它的实际含义

另一种方法是创建对象rangeChecker/notInRangeChecker,然后创建不同范围检查器的数组并创建函数checkValueAtLeastInOneRange(keyCode, rangesArray)

【讨论】:

    【解决方案2】:

    没有办法像这样明智地做类似的事情,但你可以做一些事情来尝试模仿:

    var keyCode = 40
    
    var ranges = [
      [102,Infinity],
      [0,48],
      [57,65],
      [70,97]
    ]
    
    var allowed = ranges.some(function(values){
        return keyCode > values[0] && keyCode < values[1]
    })
    
    if(allowed){
       console.log("allowed")
    }else{
      console.log("not allowed")
    } 
    

    【讨论】:

    • 不错!我喜欢你使用Infinity。我没想到。
    • @JonathanLam 是的,我不确定 keyCode 的最大可能值,所以 Infinity 是我的方法。不要忘记-Infinity ;)
    【解决方案3】:

    某些语言(例如 Python)支持链式比较,因此您可以说 42 &lt; x &lt;= y &lt; 84。但是,总的来说,我个人并不了解您描述的确切功能。不过看起来不错!

    对于小型域,例如键码,您可以将感兴趣的代码放在一个数组中并测试集合成员资格:

    if keyCode in (range(102,256)+range(0,49)+range(58,65)+range(71,97)):
        # do something
    

    + 将范围合并到一个列表中。)

    【讨论】:

      【解决方案4】:

      不,您不能删除该变量,因为每个条件都由它自己评估。 但是要重用某些检查,我建议您将它们提取到函数对象(并从另一个文件中要求它):

      var keyTester = {
          isA: function (keyCode) {
              return keyCode > 102;
          },
          isB: function (keyCode) {
              return keyCode < 48;
          },
          isC: function  (keyCode) {
              keyCode > 57 && keyCode < 65;
          }
      };
      
      if (keyTester.isA(keyCode) || keyTester.isB(keyCode) || keyTester.isC(keyCode) ... )
      

      【讨论】:

        【解决方案5】:

        另一个想法 - 为您的变量使用一个简短的别名,例如 _

        if(
            (_=keyCode) > 102 || _ < 48 || (_ > 57 && _ < 65) || ( _ > 70 && _ < 97)
        ) {
            // do something
        }
        

        确保不要将_ 用于在if 语句中不能丢弃的任何内容:)。 (_=keyCode) 用很少的额外击键来存储值,然后_ 可以在整个过程中使用。 &amp;&amp;|| 评估从左到右 (reference),所以 _ 应该在其余条件中可用。

        我做了一个快速测试:在谷歌浏览器中,

        var x=42; 
        if((_=x)<99 && _>30) { console.log(x);}
        

        有效(按预期打印42)。

        【讨论】:

        • 这是一个有趣的想法......我没有考虑过这样的事情(我也不知道_是一个有效的JS变量名)
        猜你喜欢
        • 2022-12-17
        • 2015-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-08
        • 1970-01-01
        相关资源
        最近更新 更多