根据值列表检查变量相等性

IT技术 javascript
2021-01-17 20:56:48

我正在检查一个变量,例如foo,是否与多个值相等。例如,

if( foo == 1 || foo == 3 || foo == 12 ) {
    // ...
}

关键是对于这样一个微不足道的任务,它是相当多的代码。我想出了以下内容:

if( foo in {1: 1, 3: 1, 12: 1} ) {
    // ...
}

但这并不完全吸引我,因为我必须为对象中的项目赋予冗余值。

有谁知道对多个值进行平等检查的体面方法吗?

6个回答

您可以使用数组和indexOf

if ([1,3,12].indexOf(foo) > -1)
我喜欢这个。我猜甚至可以通过原型创建一个“包含”函数,以消除> -1 的使用。
2021-03-13 20:56:48
@pimvdb:请注意,您可能需要自己的实现,因为indexOf仅在 ECMAScript 第 5 版之后可用。
2021-03-23 20:56:48
您可以使用~运算符代替> -1if ( ~[...].indexOf(foo) ) { ... }
2021-03-28 20:56:48
'>' 是否比 '!==' 更好?
2021-03-30 20:56:48

在 ECMA2016 中,您可以使用includes方法。这是我见过的最干净的方式。(所有主流浏览器都支持)

if([1,3,12].includes(foo)) {
    // ...
}
对于变量if([a,b,c].includes(foo))或字符串if(['a','b','c'].includes(foo))
2021-03-14 20:56:48
@BinodShrestha 我认为这就是我写的,除非我遗漏了什么。“对于变量......或字符串......”
2021-03-14 20:56:48
对于变量 =>if([a,b,c].includes(foo))因为引号将使其成为字符串。@HastigZusammenstellen
2021-04-08 20:56:48

使用提供的答案,我最终得到以下结果:

Object.prototype.in = function() {
    for(var i=0; i<arguments.length; i++)
       if(arguments[i] == this) return true;
    return false;
}

它可以被称为:

if(foo.in(1, 3, 12)) {
    // ...
}

编辑:我最近遇到了这个“技巧”,如果值是字符串并且不包含特殊字符,它会很有用。对于特殊字符,由于转义而变得丑陋,并且因此更容易出错。

/foo|bar|something/.test(str);

更准确地说,这将检查确切的字符串,但对于简单的相等性测试,这又变得更加复杂:

/^(foo|bar|something)$/.test(str);
天哪!我很惊讶它的工作原理 -in是 Javascript 中的一个关键字。例如,运行会function in() {}; in()导致语法错误,至少在 Firefox 中是这样,我不确定为什么您的代码没有。:-)
2021-03-15 20:56:48
@BenBlank - 仅供参考,使用关键字作为文字属性名称在第 5 版规范(2009 年 12 月)中变得有效,这就是有效的原因x.in()在第 5 版之前,您将不得不使用计算属性名称 ( x["in"]())。
2021-03-22 20:56:48
此外,扩展通常被认为是不好的做法Object.prototype,因为它会for (foo in bar)以不幸的方式影响也许将其更改为function contains(obj) { for (var i = 1; i < arguments.length; i++) if (arguments[i] === obj) return true; return false; }并将对象作为参数传递?
2021-04-04 20:56:48
如上所述,以Object.prototype这种方式扩展具有严重的缺点,并可能导致许多错误。如果你真的想扩展Object.prototype总是通过Object.defineProperty不设置enumerable描述符来扩展
2021-04-04 20:56:48
扩展 Object.prototype 是一种反模式,不应使用。改用函数。
2021-04-07 20:56:48

if(foo in L(10,20,30))如果你定义L为,你可以写

var L = function()
{
    var obj = {};
    for(var i=0; i<arguments.length; i++)
        obj[arguments[i]] = null;

    return obj;
};
我认为谨慎地指出原型函数也在数组/对象中 - 所以如果数组/对象的原型中有一个函数 'remove',如果你编码它总是会返回 true 'remove' in L(1, 3, 12),尽管你没有指定要放入列表的“删除”。
2021-04-02 20:56:48

现在您可能有更好的解决方案来解决这种情况,但我更喜欢其他方式。

const arr = [1,3,12]
if( arr.includes(foo)) { // it will return true if you `foo` is one of array values else false
  // code here    
}

我更喜欢上面的解决方案,而不是 indexOf 检查,您还需要检查索引。

包括文档

if ( arr.indexOf( foo ) !== -1 ) { }