将一个值与多个值进行比较的最漂亮的方法是什么?[复制]

What's the prettiest way to compare one value against multiple values? [duplicate]

提问人:thelastshadow 提问时间:2/3/2012 最后编辑:isherwoodthelastshadow 更新时间:2/1/2022 访问量:204112

问:

将一个值与多个选项进行比较的最漂亮的方法是什么?

我知道有很多方法可以做到这一点,但我正在寻找最简洁的方法。

我问是因为我希望这是可行的(当你看到它时,很明显它不是):

if (foobar == (foo||bar) ) {
     //do something
}
JavaScript 比较

评论

2赞 Ron van der Heijden 2/13/2013
您可以使用 javascript 测试函数,例如 This question simular 来挖掘if(/foo|bar|ow|my|javascript|works/.test( foobar )) { /*do something*/ }
0赞 Neil 3/22/2019
我在这里要指出的是,foo 不会正确评估,它不会检查栏,例如 将返回 false...1 === (2 || 1)
3赞 Loïc V 9/20/2021
有点老线程,但在 ES6 中:if ([foo,bar].includes(foobar) { //do something } 会做

答:

25赞 Guffa 2/3/2012 #1

您可以使用开关:

switch (foobar) {
  case foo:
  case bar:
    // do something
}
88赞 André Alçada Padez 2/3/2012 #2

我用来做的是将这些多个值放在一个数组中,例如

var options = [foo, bar];

然后,使用 indexOf()

if(options.indexOf(foobar) > -1){
   //do something
}

为了漂亮:

if([foo, bar].indexOf(foobar) +1){
   //you can't get any more pretty than this :)
}

对于较旧的浏览器:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/IndexOf
)

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (this == null) {
            throw new TypeError();
        }
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = 0;
        if (arguments.length > 0) {
            n = Number(arguments[1]);
            if (n != n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n != 0 && n != Infinity && n != -Infinity) {
                n = (n > 0 || -1) * Math.floor(Math.abs(n));
            }
        }
        if (n >= len) {
            return -1;
        }
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) {
            if (k in t && t[k] === searchElement) {
                return k;
            }
        }
        return -1;
    }
}

评论

2赞 Reid 2/3/2012
indexOffor arrays 仅在 IE 中从版本 9 开始提供,因此在 8 退出市场之前,我会避免使用它(不幸的是,还有很长的路要走)。也就是说,MDN 为不支持它的浏览器提供了示例实现代码。
1赞 Guffa 2/3/2012
该方法仅在 Javascript 1.6 及更高版本中受支持,因此您需要对较旧的浏览器进行回退。Array.indexOf
9赞 baptx 7/1/2020
ES6 的新方法是使用:stackoverflow.com/questions/2430000/...includes
1赞 machinekoder 6/21/2021
@baptx 这应该是第一答案。可读性更强,就像 Python 的 foo in (bar, baz) 一样。
1赞 André Alçada Padez 10/14/2021
@l33t哈哈,好一个。显然不是,但不会走得那么远......我会使用 [a, b, c, ...]。包括(val)
42赞 jfriend00 2/3/2012 #3

由于还没有人添加明显的解决方案,该解决方案适用于两个比较,因此我将提供它:

if (foobar === foo || foobar === bar) {
     //do something
}

而且,如果你有很多值(可能是数百或数千个),那么我建议制作一个 Set,因为这会使代码非常干净和简单,而且在运行时速度很快:

// pre-construct the Set
var tSet = new Set(["foo", "bar", "test1", "test2", "test3", ...]);

// test the Set at runtime
if (tSet.has(foobar)) {
    // do something
}

对于 ES6 之前,您可以获得一个 Set polyfill,其中有很多。另一个答案中描述了一个。

评论

1赞 Jack G 6/30/2018
Set仍然比字符串比较的本机优化慢。让浏览器进行优化。试图超越浏览器的人几乎总是以慢得多的代码告终。
2赞 jfriend00 6/30/2018
@JackGiffin - 你在这里有什么建议?我回答的第一部分只是最简单的比较,JS 引擎可以随心所欲地对其进行优化。我的答案的第二部分使用 a 针对的是你有很多值可以比较(数百或数千)的情况。我不明白你在建议什么而不是这些,或者你认为这些建议有什么问题?Set
1赞 DIES 10/7/2020
Set 如何比普通 Array: 更好?if(['foo', 'bar'].includes(value))
6赞 jfriend00 10/7/2020
@DIES - A 使用哈希表查找,而使用线性搜索。当集合中包含多个项目时,Set 应该可以更快地查看某个项目是否在 .另外,论坛可以防止重复。Set.includes()Set.add()Set
0赞 Dale Ryan 3/11/2023
在处理大量数据时,Set.has 绝对比 Array.includes 快。在处理小型数据集时,您可以摆脱 Array.includes。
1赞 JamieSee 2/3/2012 #4

(foobar == foo || foobar == bar)否则,如果仅根据单个整数、枚举值或 String 对象比较表达式,则可以使用 switch。请参见 switch 语句。您也可以使用安德烈·阿尔萨达·帕德斯 (André Alçada Padez) 建议的方法。最终,您的选择将取决于您正在做的事情的细节。

评论

0赞 Jack G 6/30/2018
上面已经提到过三次了。在堆栈溢出时,您应该只发布不在问题现有答案中的解决方案。
0赞 jfriend00 6/30/2018
@JackGiffin - 如果您查看时间戳,在此之前没有发布多个其他答案来显示此解决方案。此处的答案不一定按发布顺序显示。只有我的答案显示这似乎在它之前,而且只在它之前 3 秒,所以不是作者会看到的。公认的答案甚至在这之后出现。再说一次,我不确定你为什么要抨击一个 6 岁的答案。
0赞 Jack G 7/4/2018
@jfriend00 你是对的!我研究了所有的时间戳,大卫是骗子,而不是杰米西。JamieSee比david早14分钟得到了答案,David也有完全相同的答案,但david得到了荣誉,而JamieSee没有。让我们为JamieSee更合理的答案投赞成票。
0赞 jfriend00 7/4/2018
@JackGiffin - 这不仅关乎谁先到达那里。一个好的答案还有其他方面,除了它是否在某处有正确的内容,比如它写得有多清楚,解释做得有多好,等等......OP 甚至评论了大卫的回答,说这是“最清晰的”。甚至有时候,写另一个答案是合适的,因为现有的答案都没有很好地呈现和解释事情。在这种情况下,我并没有暗示任何事情,只是成为第一并不是唯一的标准。
0赞 jfriend00 7/4/2018
@JackGiffin - 复选标记应该转到最佳答案。这是一场看谁能写出最佳答案的比赛。允许多次提交。直接复制而不添加有价值的东西是不受欢迎的,但试图写一个更好的答案来更好地解释事情或解释一些新的方面不仅是允许的,而且是可取的。同样,我并不是在暗示这个特殊情况,只是一般性地发表评论。
168赞 david 2/3/2012 #5

不要试图太偷偷摸摸,尤其是当它不必要地影响性能时。 如果你真的有一大堆比较要做,只需很好地格式化它。

if (foobar === foo ||
    foobar === bar ||
    foobar === baz ||
    foobar === pew) {
     //do something
}

评论

39赞 wenzul 8/11/2015
如果您将降序概率排序为真,则可以加快速度。:)
0赞 LCIII 7/16/2021
在我的世界里,可读性===漂亮。这是最易读的。
0赞 wtanaka.com 7/30/2021
如果要比较的项目在编写代码时已知,但可能不适合要比较的项目是可变的,则此方法有效。
0赞 Денищук Павло Миколайович 9/4/2021
你可以使用 Array.prototype.every(): [foo, bar].every(elem => elem === comparedValue);
1赞 Gss Venkatesh 8/30/2022
请改用 includes if (['foo', 'bar', 'baz', 'pew'].includes(foobar)) { //do something }
18赞 lucideer 2/13/2013 #6

只是为了踢球,因为这个问答似乎是关于语法微观分析的,这是对安德烈·阿尔萨达·帕德斯(André Alçada Padez)建议的微小修改:

(当然,还包括他包括的 IE9 之前的垫片/shiv/polyfill)

if (~[foo, bar].indexOf(foobar)) {
    // pretty
}

评论

3赞 Pavel Levin 6/25/2019
!!~['foo', 'bar'].indexOf('foo')🙃
0赞 Unmitigated 2/4/2023
@PavelLevin 您不需要,因为已经测试了表达式的真实性。!!if
13赞 Ionică Bizău 6/7/2013 #7

为什么不像下面这样使用 from 数组?indexOf

if ([foo, bar].indexOf(foobar) !== -1) {
    // do something
}

只是普通的 Javascript,没有框架或库,但它不适用于 IE < 9

评论

0赞 Jack G 6/30/2018
已经提到了两次几乎相同的代码片段。
0赞 MrBB 12/23/2021
非常有趣的使用方式。我没有想象过这种语法。感谢您以这种聪明的方式分享。
0赞 Joel Barba 3/25/2015 #8

我喜欢使用数组测试 indexOf 的漂亮形式,但请注意,这不适用于所有浏览器(因为旧的 IExplorers 中不存在 Array.prototype.indexOf)。

但是,通过将 jQuery 与 $.inArray() 函数一起使用,也有类似的方法:

if ($.inArray(field, ['value1', 'value2', 'value3']) > -1) {
    alert('value ' + field + ' is into the list'); 
}

它可能会更好,因此您不应该测试 indexOf 是否存在。

比较时要小心(不要使用 == true/false),因为 $.inArray 返回已找到值的匹配位置的索引,如果索引为 0,则当它真正存在于数组中时将是 false。

评论

0赞 Jack G 6/30/2018
请不要使用 jQuery(除非你确实想要慢代码和慢页面加载速度,在这种情况下,去吧——我没有人可以阻止疯狂)