找出JavaScript数组是否包含值的最简洁有效的方法是什么?

这是我知道的唯一方法:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

有没有更好、更简洁的方法来实现这一点?

这与堆栈溢出问题密切相关。在JavaScript数组中查找项目的最佳方法是什么?它解决了使用indexOf查找数组中的对象的问题。


当前回答

function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

如果找到,则返回数组索引;如果找不到,则返回-1

其他回答

扩展JavaScript数组对象是一个非常糟糕的主意,因为您在for-in循环中引入了新的财产(自定义方法),这可能会破坏现有的脚本。几年前,Prototype库的作者不得不重新设计他们的库实现,以消除这种情况。

如果您不需要担心与页面上运行的其他JavaScript的兼容性,那就去尝试吧,否则,我会推荐更尴尬但更安全的独立函数解决方案。

一个衬垫:

function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}

检查数组JavaScript中是否存在值的最佳默认方法是some()

Array.prototype.some()

some()方法测试数组中是否至少有一个元素通过了所提供函数实现的测试。如果在数组中找到所提供的函数返回true的元素,则返回true;否则返回false。它不会修改数组。

const array = [1, 2, 3, 4, 5];

// checks whether an element is even
const even = (element) => element % 2 === 0;

console.log(array.some(even));
// expected output: true

some方法是浏览器兼容性中最好的方法

有关更多文档Array.prototype.some()-JavaScript | MDN

您还可以使用另外两个方法:find()和includes()。用这些方法你可以得到你的结果,但不是最好的。

Array.prototype.find()-JavaScript | MDN

Array.prototype.includes()-JavaScript | MDN

Object.keys,用于获取对象的所有属性名称,并筛选与指定字符串完全或部分匹配的所有值。

函数filterByValue(数组,字符串){返回array.filter(o=>Object.keys(o).some(k=>o[k].toLowerCase().includes(string.toLoweCase()));}常量数组OfObject=[{name:“Paul”,country:'加拿大',}, {name:'Lea',国家:“意大利”,}, {name:“John”,country:'意大利'}];console.log(filterByValue(arrayOfObject,'lea'));//〔{名称:‘Lea’,国家:‘意大利’}〕console.log(filterByValue(arrayOfObject,'ita'));//[{名称:“Lea”,国家:“Italy”},{名称“John”,国家“Italy'”}]

您还可以按特定关键字进行筛选,例如。

Object.keys(o).some(k => o.country.toLowerCase().includes(string.toLowerCase())));

现在,您可以在过滤后检查数组计数,以检查值是否包含。

希望这有帮助。

适用于所有现代浏览器的解决方案:

function contains(arr, obj) {
  const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
  return arr.some(item => JSON.stringify(item) === stringifiedObj);
}

用法:

contains([{a: 1}, {a: 2}], {a: 1}); // true

IE6+解决方案:

function contains(arr, obj) {
  var stringifiedObj = JSON.stringify(obj)
  return arr.some(function (item) {
    return JSON.stringify(item) === stringifiedObj;
  });
}

// .some polyfill, not needed for IE9+
if (!('some' in Array.prototype)) {
  Array.prototype.some = function (tester, that /*opt*/) {
    for (var i = 0, n = this.length; i < n; i++) {
      if (i in this && tester.call(that, this[i], i, this)) return true;
    } return false;
  };
}

用法:

contains([{a: 1}, {a: 2}], {a: 1}); // true

为什么使用JSON.stringify?

Array.indexOf和Array.includes(以及这里的大多数答案)只通过引用而不是通过值进行比较。

[{a: 1}, {a: 2}].includes({a: 1});
// false, because {a: 1} is a new object

奖金

未经优化的ES6单缸套:

[{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
// true

注:如果键的顺序相同,则按值比较对象的效果会更好,因此为了安全起见,您可以首先使用以下包对键进行排序:https://www.npmjs.com/package/sort-keys


使用性能优化更新了contains函数。谢谢你指出这一点。