我正在检查一个变量,例如foo,是否等于多个值。例如,
if( foo == 1 || foo == 3 || foo == 12 ) {
// ...
}
关键是,对于这样一个琐碎的任务,这是很多代码。我提出以下内容:
if( foo in {1: 1, 3: 1, 12: 1} ) {
// ...
}
但这也不完全吸引我,因为我必须为对象中的项目提供冗余值。
有谁知道对多个值进行相等性检查的体面方法?
我正在检查一个变量,例如foo,是否等于多个值。例如,
if( foo == 1 || foo == 3 || foo == 12 ) {
// ...
}
关键是,对于这样一个琐碎的任务,这是很多代码。我提出以下内容:
if( foo in {1: 1, 3: 1, 12: 1} ) {
// ...
}
但这也不完全吸引我,因为我必须为对象中的项目提供冗余值。
有谁知道对多个值进行相等性检查的体面方法?
Answers:
您可以使用数组和indexOf:
if ([1,3,12].indexOf(foo) > -1)
indexOf只有自ECMAScript 5版以来才可用。
在ECMA2016中,可以使用include方法。这是我所见过的最干净的方式。(除IE之外,所有主流浏览器均支持(链接中包含“填充”)
if([1,3,12].includes(foo)) {
// ...
}
if([a,b,c].includes(foo))或字符串if(['a','b','c'].includes(foo))
if([a,b,c].includes(foo))因为引号会将其设置为字符串。@HastigZusammenstellen
使用提供的答案,我得出以下结论:
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中会导致语法错误,但我不确定为什么您的代码没有。:-)
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; }并将对象作为参数传递?
Object.prototype与您也提到的扩展相比,帮助程序类可以更好地完成此工作。但是,我确实更喜欢这种方式,因为检查的符号很可爱,就像foo.in(1, 2, "test", Infinity)馅饼一样容易。
in()在Chrome上以常规方式定义函数也失败了,但是原型
你可以写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' in L(1, 3, 12),它也始终返回true。指定“删除”以放入列表中。
这很容易扩展和读取:
switch (foo) {
case 1:
case 3:
case 12:
// ...
break
case 4:
case 5:
case 6:
// something else
break
}
但不一定更容易:)
var a = [1,2,3];
if ( a.indexOf( 1 ) !== -1 ) { }
请注意,indexOf不在核心ECMAScript中。您需要为IE和不支持Array.prototype.indexOf的其他浏览器提供一个代码段。
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(searchElement /*, fromIndex */)
{
"use strict";
if (this === void 0 || 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)
n = 0;
else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))
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;
};
}
另外,由于要检查结果的值都是唯一的,因此也可以使用Set.prototype.has()。
var valid = [1, 3, 12];
var goodFoo = 3;
var badFoo = 55;
// Test
console.log( new Set(valid).has(goodFoo) );
console.log( new Set(valid).has(badFoo) );
现在您可能有更好的解决方案来解决此问题,但是我更喜欢其他方式。
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 check。
if ( arr.indexOf( foo ) !== -1 ) { }
我喜欢接受的答案,但认为使它也能够采用数组会很巧妙,因此我将其扩展为:
Object.prototype.isin = function() {
for(var i = arguments.length; i--;) {
var a = arguments[i];
if(a.constructor === Array) {
for(var j = a.length; j--;)
if(a[j] == this) return true;
}
else if(a == this) return true;
}
return false;
}
var lucky = 7,
more = [7, 11, 42];
lucky.isin(2, 3, 5, 8, more) //true
您可以通过更改==为删除类型强制===。
这是一个辅助的辅助函数:
const letters = ['A', 'B', 'C', 'D'];
function checkInList(arr, val) {
return arr.some(arrVal => val === arrVal);
}
checkInList(letters, 'E'); // false
checkInList(letters, 'A'); // true
const valToCheck = 'E'; const check = ['A', 'B', 'C', 'D'].some(option => option === valToCheck); // false
includes会变成更好的选择,例如@alister的答案:const valToCheck = 'E'; const check = ['A', 'B', 'C', 'D'].includes(valToCheck); // false
为了后代,您可能希望使用正则表达式作为替代。相当不错的浏览器支持(请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#Browser_compatibility)
试试这个
if (foo.toString().match(/^(1|3|12)$/)) {
document.write('Regex me IN<br>');
} else {
document.write('Regex me OUT<br>');
}