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

这是我知道的唯一方法:

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

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

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


当前回答

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())));

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

希望这有帮助。

其他回答

而array.indexOf(x)=-1是实现这一点的最简洁的方法(并且已经被非Internet Explorer浏览器支持了十多年……),它不是O(1),而是O(N),这很可怕。如果您的数组不会改变,您可以将数组转换为哈希表,然后执行表[x]==未定义或==未定义:

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

演示:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(不幸的是,虽然您可以创建Array.prototype.contains来“冻结”数组并将哈希表存储在this._cache中,但如果您选择稍后编辑数组,则会产生错误的结果。与Python不同,JavaScript没有足够的钩子来保持这种状态。)

将唯一项目添加到其他列表

searchResults: [
                {
                    name: 'Hello',
                    artist: 'Selana',
                    album: 'Riga',
                    id: 1,
                },
                {
                    name: 'Hello;s',
                    artist: 'Selana G',
                    album: 'Riga1',
                    id: 2,
                },
                {
                    name: 'Hello2',
                    artist: 'Selana',
                    album: 'Riga11',
                    id: 3,
                }
            ],
            playlistTracks: [
              {
                name: 'Hello',
                artist: 'Mamunuus',
                album: 'Riga',
                id: 4,
              },
              {
                name: 'Hello;s',
                artist: 'Mamunuus G',
                album: 'Riga1',
                id: 2,
              },
              {
                name: 'Hello2',
                artist: 'Mamunuus New',
                album: 'Riga11',
                id: 3,
              }
            ],
            playlistName: "New PlayListTrack",
        };
    }

    // Adding an unique track in the playList
    addTrack = track => {
      if(playlistTracks.find(savedTrack => savedTrack.id === track.id)) {
        return;
      }
      playlistTracks.push(track);

      this.setState({
        playlistTracks
      })
    };

检查数组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

想一想,如果您多次调用此调用,那么使用关联数组Map使用哈希函数进行查找会更有效。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

我查看了提交的答案,发现只有通过引用搜索对象时,这些答案才适用。具有参考对象比较的简单线性搜索。

但是,假设您没有对象的引用,如何在数组中找到正确的对象?您必须对每个对象进行线性和深度比较。想象一下,如果列表太大,并且其中的对象非常大,包含大量文本。随着阵列中元素的数量和大小,性能急剧下降。

您可以将对象字符串化并将其放入本机哈希表中,但这样您就有了记住这些键的数据冗余,因为JavaScript将它们保存为“for i in obj”,您只需要检查对象是否存在,也就是说,您拥有该键。

我考虑了一段时间来构建一个JSON模式验证器,我为本地哈希表设计了一个简单的包装器,类似于唯一的哈希表实现,但一些优化异常我留给本地哈希表处理。它只需要性能基准。。。所有详细信息和代码都可以在我的博客上找到:http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/我将很快发布基准结果。

完整的解决方案如下所示:

var a = {'a':1,
 'b':{'c':[1,2,[3,45],4,5],
 'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
 'u':'lol'},
 'e':2};

 var b = {'a':1, 
 'b':{'c':[2,3,[1]],
 'd':{'q':3,'b':{'b':3}}},
 'e':2};

 var c = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

 var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init

 hc.put({a:1, b:1});
 hc.put({b:1, a:1});
 hc.put(true);
 hc.put('true');
 hc.put(a);
 hc.put(c);
 hc.put(d);
 console.log(hc.exists('true'));
 console.log(hc.exists(a));
 console.log(hc.exists(c));
 console.log(hc.exists({b:1, a:1}));
 hc.remove(a);
 console.log(hc.exists(c));