如何检查数组是否包含JavaScript中的值?

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

这是我知道的唯一方法:

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

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

这与Stack Overflow问题在JavaScript数组中查找项目的最佳方法?密切相关,该问题解决了使用indexOf在数组中查找对象的问题。

3278696 次浏览

如果您使用的是JavaScript 1.6或更高版本(Firefox 1.5或更高版本),您可以使用Array.index。否则,我认为您最终会得到与原始代码相似的东西。

#0也许吧,但它是“ECMA-262标准的JavaScript扩展;因此,它可能不存在于该标准的其他实现中。”

示例:

[1, 2, 3].indexOf(1) => 0["foo", "bar", "baz"].indexOf("bar") => 1[1, 2, 3].indexOf(4) => -1

AFAICS微软没有没有提供某种替代方案,但如果您愿意,您可以向Internet Explorer(和其他不支持indexOf的浏览器)中的数组添加类似的功能,作为快速谷歌搜索显示(例如,这一个)。

2019年更新:这个答案来自2008年(11岁!),与现代JS的使用无关。承诺的性能改进是基于当时浏览器中完成的基准测试。它可能与现代JS执行上下文无关。如果你需要一个简单的解决方案,请寻找其他答案。如果你需要最佳性能,请在相关的执行环境中为自己基准测试。

正如其他人所说,通过数组进行迭代可能是最好的方法,但它已经证明递减while循环是JavaScript中迭代的最快方法。所以你可能想重写你的代码,如下所示:

function contains(a, obj) {var i = a.length;while (i--) {if (a[i] === obj) {return true;}}return false;}

当然,你也可以扩展Array原型:

Array.prototype.contains = function(obj) {var i = this.length;while (i--) {if (this[i] === obj) {return true;}}return false;}

现在您可以简单地使用以下内容:

alert([1, 2, 3].contains(2)); // => truealert([1, 2, 3].contains('2')); // => false

这是Array.indexOfJavaScript 1.6兼容实现:

if (!Array.indexOf) {Array.indexOf = [].indexOf ?function(arr, obj, from) {return arr.indexOf(obj, from);} :function(arr, obj, from) { // (for IE6)var l = arr.length,i = from ? parseInt((1 * from) + (from < 0 ? l : 0), 10) : 0;i = i < 0 ? 0 : i;for (; i < l; i++) {if (i in arr && arr[i] === obj) {return i;}}return -1;};}

扩展JavaScriptArray对象是一个非常糟糕的主意,因为您将新属性(您的自定义方法)引入for-in循环,这可能会破坏现有脚本。几年前,原型库的作者不得不重新设计他们的库实现来删除这种东西。

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

以下是如何原型做的

/***  Array#indexOf(item[, offset = 0]) -> Number*  - item (?): A value that may or may not be in the array.*  - offset (Number): The number of initial items to skip before beginning the*      search.**  Returns the position of the first occurrence of `item` within the array &mdash; or*  `-1` if `item` doesn't exist in the array.**/function indexOf(item, i) {i || (i = 0);var length = this.length;if (i < 0) i = length + i;for (; i < length; i++)if (this[i] === item) return i;return -1;}

另请参阅这里了解他们如何连接它。

现代浏览器有#0,除了IE之外,每个人都有完全得到广泛支持

console.log(['joe', 'jane', 'mary'].includes('jane')); //true

You can also use Array#indexOf, which is less direct, but doesn't require polyfills for outdated browsers.

console.log(['joe', 'jane', 'mary'].indexOf('jane') >= 0); //true


许多框架也提供类似的方法:

  • jQuery:#0
  • Underscore.js:#0(别名为_.include_.includes
  • Dojo工具包:#0
  • 原型:#0
  • MooTools:#0
  • MochiKit:#0
  • MS Ajax:#0
  • 分机:#0
  • Lodash:#0(在4.0.0之前是_.contains
  • Ramda:#0

请注意,一些框架将其作为函数实现,而另一些框架将该函数添加到数组原型中。

开箱即用,如果您多次进行此调用,使用关联数组 a Map使用哈希函数进行查找要有效得多。

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

只是另一种选择

// usage: if ( ['a','b','c','d'].contains('b') ) { ... }Array.prototype.contains = function(value){for (var key in this)if (this[key] === value) return true;return false;}

要小心,因为使用自定义方法重载javascript数组对象可能会破坏其他javascript的行为,从而导致意外行为。

如果你在数组中反复检查对象的存在,你可能应该看看

  1. 通过在数组中执行插入排序来始终保持数组排序(将新对象放在正确的位置)
  2. 使更新对象作为删除+排序插入操作和
  3. 在你的contains(a, obj)中使用二分查找查找。

字面意思:

(使用Firefox v3.6,如前所述有for-in警告(但是,下面的用法可能会为此目的而支持for-in!也就是说,通过属性索引枚举实际存在的数组元素(但是,特别是,数组length属性未在for-in属性列表中枚举!).).)

(拖放以下完整的URI用于即时模式浏览器测试。)

JavaScript:

  function ObjInRA(ra){var has=false; for(i in ra){has=true; break;} return has;}
function check(ra){return ['There is ',ObjInRA(ra)?'an':'NO',' object in [',ra,'].'].join('')}alert([check([{}]), check([]), check([,2,3]),check(['']), '\t (a null string)', check([,,,])].join('\n'));

其中显示:

There is an object in [[object Object]].There is NO object in [].There is an object in [,2,3].There is an object in [].(a null string)There is NO object in [,,].

皱纹:如果寻找“特定”对象,请考虑:

JavaScript:alert({}!={}); alert({}!=={});

因此:

JavaScript:

 obj = {prop:"value"};ra1 = [obj];ra2 = [{prop:"value"}];alert(ra1[0] == obj);alert(ra2[0] == obj);

通常ra2被认为“包含”obj作为文字实体{prop:"value"}

一个非常粗糙、基本、幼稚(如代码需要增强)的解决方案:

JavaScript:

  obj={prop:"value"};   ra2=[{prop:"value"}];alert(ra2 . toSource() . indexOf( obj.toSource().match(/^.(.*).$/)[1] ) != -1 ?'found' :'missing' );

参见ref:在JavaScript数组中搜索对象

用途:

Array.prototype.contains = function(x){var retVal = -1;
// x is a primitive typeif(["string","number"].indexOf(typeof x)>=0 ){ retVal = this.indexOf(x);}
// x is a functionelse if(typeof x =="function") for(var ix in this){if((this[ix]+"")==(x+"")) retVal = ix;}
//x is an object...else {var sx=JSON.stringify(x);for(var ix in this){if(typeof this[ix] =="object" && JSON.stringify(this[ix])==sx) retVal = ix;}}
//Return False if -1 else number if numeric otherwise stringreturn (retVal === -1)?false : ( isNaN(+retVal) ? retVal : +retVal);}

我知道这不是最好的方式,但由于没有本机的I比较对象之间的交互方式,我想这是比较数组中的两个实体所能达到的最接近的方式。此外,扩展Array对象可能不是明智的做法,但有时没关系(如果你知道它和权衡)。

假设您定义了一个数组,如下所示:

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

下面是检查是否有3的三种方法。它们都返回truefalse

本机数组方法(自ES2016)(兼容性表

array.includes(3) // true

自定义Array方法(ES2016之前)

// Prefixing the method with '_' to avoid name clashesObject.defineProperty(Array.prototype, '_includes', { value: function (v) { return this.indexOf(v) !== -1 }})array._includes(3) // true

简单的功能

const includes = (a, v) => a.indexOf(v) !== -1includes(array, 3) // true

虽然array.indexOf(x)!=-1是最简洁的方式(并且已经被非Internet Explorer浏览器支持了十多年…),但它不是O(1),而是O(N),这很糟糕。如果你的数组不会改变,你可以将你的数组转换为哈希表,然后执行table[x]!==undefined===undefined

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来“冻结”数组并在其中存储一个哈希表。_cache两行,如果你选择稍后编辑数组,这将给出错误的结果。JavaScript没有足够的钩子让你保持这种状态,不像Python。)

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

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

类似的事情:通过“search lambda”查找第一个元素:

Array.prototype.find = function(search_lambda) {return this[this.map(search_lambda).indexOf(true)];};

用法:

[1,3,4,5,8,3,5].find(function(item) { return item % 2 == 0 })=> 4

在coffeescript中:

Array.prototype.find = (search_lambda) -> @[@map(search_lambda).indexOf(true)]

正如其他人提到的,您可以使用Array.indexOf,但它并不适用于所有浏览器。这是https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf中的代码,使其在旧浏览器中相同。

indexOf是ECMA-262标准的最新补充;因此它可能会并非存在于所有浏览器中。您可以通过插入脚本开头的以下代码,允许使用indexOf在不支持它的实现中。这算法正是ECMA-262第5版中规定的算法,假设对象、TypeError、数字、Math.floor、Math.abs和Math.max#36825;有其原始价值

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 > 1) {n = Number(arguments[1]);if (n != n) { // shortcut for verifying if it's NaNn = 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;}}

我查看了提交的答案,发现它们仅适用于通过引用搜索对象。一个简单的线性搜索与参考对象比较。

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

您可以字符串化对象并将它们放在本机哈希表中,但是您将拥有记住这些键的数据冗余,因为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));

用途:

function isInArray(array, search){return array.indexOf(search) >= 0;}
// Usageif(isInArray(my_array, "my_value")){//...}

用途:

var myArray = ['yellow', 'orange', 'red'] ;
alert(!!~myArray.indexOf('red')); //true

演示

要确切地知道tilde~在这一点上做了什么,请参阅此问题波浪号在表达式前面做什么?

ECMAScript 6在查找上有一个优雅的建议。

查找方法对每个元素执行一次回调函数存在于数组中,直到它找到一个回调返回true的数组值。如果找到这样的元素,则查找立即返回值该元素的。否则,查找返回未定义。回调是仅对具有赋值的数组的索引调用;它不会对已删除或从未删除过的索引调用已分配值。

这里是MDN留档

查找功能是这样工作的。

function isPrime(element, index, array) {var start = 2;while (start <= Math.sqrt(element)) {if (element % start++ < 1) return false;}return (element > 1);}
console.log( [4, 6, 8, 12].find(isPrime) ); // Undefined, not foundconsole.log( [4, 5, 8, 12].find(isPrime) ); // 5

您可以通过定义函数在ECMAScript 5及以下版本中使用它。

if (!Array.prototype.find) {Object.defineProperty(Array.prototype, 'find', {enumerable: false,configurable: true,writable: true,value: function(predicate) {if (this == null) {throw new TypeError('Array.prototype.find called on null or undefined');}if (typeof predicate !== 'function') {throw new TypeError('predicate must be a function');}var list = Object(this);var length = list.length >>> 0;var thisArg = arguments[1];var value;
for (var i = 0; i < length; i++) {if (i in list) {value = list[i];if (predicate.call(thisArg, value, i, list)) {return value;}}}return undefined;}});}

我使用以下内容:

Array.prototype.contains = function (v) {return this.indexOf(v) > -1;}
var a = [ 'foo', 'bar' ];
a.contains('foo'); // truea.contains('fox'); // false

上面的答案假设原始类型,但如果您想找出数组是否包含具有某些特征的对象Array.prototype.some()是一个优雅的解决方案:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]
items.some(item => item.a === '3')  // returns trueitems.some(item => item.a === '4')  // returns false

它的好处是,一旦找到元素,迭代就会中止,因此可以节省不必要的迭代周期。

此外,它非常适合if语句,因为它返回一个布尔值:

if (items.some(item => item.a === '3')) {// do something}

*正如Jamess在评论中指出的那样,在2018年9月回答时,完全支持Array.prototype.some()caniuse.com支持表

我们使用这个片段(适用于对象、数组、字符串):

/** @function* @name Object.prototype.inArray* @description Extend Object prototype within inArray function** @param {mix}    needle       - Search-able needle* @param {bool}   searchInKey  - Search needle in keys?**/Object.defineProperty(Object.prototype, 'inArray',{value: function(needle, searchInKey){
var object = this;
if( Object.prototype.toString.call(needle) === '[object Object]' ||Object.prototype.toString.call(needle) === '[object Array]'){needle = JSON.stringify(needle);}
return Object.keys(object).some(function(key){
var value = object[key];
if( Object.prototype.toString.call(value) === '[object Object]' ||Object.prototype.toString.call(value) === '[object Array]'){value = JSON.stringify(value);}
if(searchInKey){if(value === needle || key === needle){return true;}}else{if(value === needle){return true;}}});},writable: true,configurable: true,enumerable: false});

用法:

var a = {one: "first", two: "second", foo: {three: "third"}};a.inArray("first");          //truea.inArray("foo");            //falsea.inArray("foo", true);      //true - search by keysa.inArray({three: "third"}); //true
var b = ["one", "two", "three", "four", {foo: 'val'}];b.inArray("one");         //trueb.inArray('foo');         //falseb.inArray({foo: 'val'})   //trueb.inArray("{foo: 'val'}") //false
var c = "String";c.inArray("S");        //truec.inArray("s");        //falsec.inArray("2", true);  //truec.inArray("20", true); //false
function contains(a, obj) {return a.some(function(element){return element == obj;})}

Array.prototype.some()在第5版中被添加到ECMA-262标准中

ECMAScript 7引入了#0

它可以像这样使用:

[1, 2, 3].includes(2); // true[1, 2, 3].includes(4); // false

它还接受可选的第二个参数fromIndex

[1, 2, 3].includes(3, 3); // false[1, 2, 3].includes(3, -1); // true

与使用严格平等比较indexOf不同,includes使用零值类型相等算法进行比较。这意味着您可以检测数组是否包含NaN

[1, 2, NaN].includes(NaN); // true

indexOf不同的是,includes不会跳过缺少的索引:

new Array(5).includes(undefined); // true

它可以多填充使其在所有浏览器上工作。

单行:

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

希望更快的双向indexOf/lastIndexOf替代方案

2015

虽然新方法#0非常好,但目前支持基本为零。

很长一段时间以来,我一直在思考一种方法来替换缓慢的indexOf/lastIndexOf函数。

已经找到了一种高性能的方法,查看顶部的答案。从这些答案中,我选择了@Damir Zekic发布的contains函数,这应该是最快的一个。但它也指出基准测试来自2008年,因此已经过时。

我也更喜欢while而不是for,但不是出于特定的原因,我结束了使用for循环编写函数。它也可以用while --完成。

我很好奇,如果我在执行时检查数组的两边,迭代是否会慢得多。显然不是,所以这个函数比投票最多的函数快两倍。显然它也比原生快。这是在现实世界的环境中,你永远不知道你正在搜索的值是在数组的开头还是结尾。

当您知道您刚刚推送了一个值的数组时,使用lastIndexOf可能仍然是最好的解决方案,但如果您必须遍历大型数组并且结果可能无处不在,这可能是一个可靠的解决方案,可以使事情变得更快。

双向indexOf/lastIndexOf

function bidirectionalIndexOf(a, b, c, d, e){for(c=a.length,d=c*1; c--; ){if(a[c]==b) return c; //or this[c]===bif(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b}return -1}
//UsagebidirectionalIndexOf(array,'value');

性能测试

https://jsbench.me/7el1b8dj80

作为测试,我创建了一个包含100k条目的数组。

三个查询:在数组的开头、中间和末尾。

我希望你也觉得这很有趣,并测试性能。

注意:如您所见,我稍微修改了contains函数以反映indexOflastIndexOf输出(所以基本上是trueindexfalse-1)。这不应该伤害它。

数组原型变体

Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){for(c=this.length,d=c*1; c--; ){if(this[c]==b) return c; //or this[c]===bif(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b}return -1},writable:false, enumerable:false});
// Usagearray.bidirectionalIndexOf('value');

该函数也可以很容易地修改为返回true或false,甚至是对象、字符串或任何它是什么。

这里是while变体:

function bidirectionalIndexOf(a, b, c, d){c=a.length; d=c-1;while(c--){if(b===a[c]) return c;if(b===a[d-c]) return d-c;}return c}
// UsagebidirectionalIndexOf(array,'value');

这怎么可能?

我认为在数组中获取反射索引的简单计算非常简单,比实际循环迭代快两倍。

这是一个复杂的示例,每次迭代执行三次检查,但这只能通过较长的计算来实现,这会导致代码速度减慢。

https://web.archive.org/web/20151019160219/http://jsperf.com/bidirectionalindexof/2

使用洛达什的一些函数。

它简洁、准确,并具有强大的跨平台支持。

接受的答案甚至不符合要求。

职位要求:推荐最简洁有效的方法来确定JavaScript数组是否包含对象。

接受答案:

$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])> -1

我的建议:

_.some([{'a': 1}, {'b': 2}], {'b': 2})> true

备注:

$. inArray可以很好地确定标量值是否存在于标量数组中…

$.inArray(2, [1,2])> 1

…但是这个问题显然要求一种有效的方法来确定对象是否包含在数组中。

为了同时处理标量和对象,你可以这样做:

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)

可以使用设置,其中包含方法“has()”:

function contains(arr, obj) {var proxy = new Set(arr);if (proxy.has(obj))return true;elsereturn false;}
var arr = ['Happy', 'New', 'Year'];console.log(contains(arr, 'Happy'));

绝不是最好的,但我只是变得有创意,增加了曲目。

不要用这个

Object.defineProperty(Array.prototype, 'exists', {value: function(element, index) {
var index = index || 0
return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)}})

// Outputs 1console.log(['one', 'two'].exists('two'));
// Outputs -1console.log(['one', 'two'].exists('three'));
console.log(['one', 'two', 'three', 'four'].exists('four'));

你也可以使用这个技巧:

var arrayContains = function(object) {return (serverList.filter(function(currentObject) {if (currentObject === object) {return currentObject}else {return false;}}).length > 0) ? true : false}

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

function contains(arr, obj) {const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iterationreturn 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.indexOfArray.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


使用perf优化更新了contains函数。感谢itinance指出。

或者这个解决方案:

Array.prototype.includes = function (object) {return !!+~this.indexOf(object);};

好的,你可以只优化您代码来获得结果!

有很多方法可以做到这一点,它们更干净更好,但我只是想得到你的模式并应用于使用JSON.stringify,只需在你的情况下做这样的事情:

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

使用idnexOf()是一个很好的解决方案,但您应该隐藏嵌入式实现indexOf()函数,该函数使用~运算符返回-1:

function include(arr,obj) {return !!(~arr.indexOf(obj));}
  1. 使用Array.indexOf(Object)
  2. 使用ECMA 7可以使用Array.includes(Object)
  3. 使用ECMA 6,您可以使用Array.find(FunctionName),其中FunctionName是用户定义的函数来搜索数组中的对象。

    希望有帮助!

我正在做一个项目,我需要一个像pythonset这样的功能,它删除所有重复的值并返回一个新列表,所以我写了这个函数可能对某人有用

function set(arr) {var res = [];for (var i = 0; i < arr.length; i++) {if (res.indexOf(arr[i]) === -1) {res.push(arr[i]);}}return res;}

它有一个参数:对象的数组编号。数组中的每个对象都有两个由x和y表示的整数属性。该函数必须返回数组中满足numbers.x == numbers.y的所有此类对象的计数

var numbers = [ { x: 1, y: 1 },{ x: 2, y: 3 },{ x: 3, y: 3 },{ x: 3, y: 4 },{ x: 4, y: 5 } ];var count = 0;var n = numbers.length;for (var i =0;i<n;i++){if(numbers[i].x==numbers[i].y){count+=1;}}
alert(count);

如果你正在使用ES6,你可以使用一个集合:

function arrayHas( array, element ) {const s = new Set(array);return s.has(element)}

这应该是更多的性能比只是任何其他方法

我建议使用下划线库,因为它返回值并且所有浏览器都支持它。

下划线

 var findValue = _.find(array, function(item) {return item.id == obj.id;});

简单解决方案:ES6功能“包括”方法

let arr = [1, 2, 3, 2, 3, 2, 3, 4];
arr.includes(2) // true
arr.includes(93) // false

除了其他人所说的,如果您没有要在数组中搜索的对象的引用,那么您可以这样做。

let array = [1, 2, 3, 4, {"key": "value"}];
array.some((element) => JSON.stringify(element) === JSON.stringify({"key": "value"})) // true
array.some((element) => JSON.stringify(element) === JSON.stringify({})) // true

如果任何元素与给定条件匹配,Array.some返回true;如果没有任何元素与给定条件匹配,则返回false。

    function countArray(originalArray) {     
var compressed = [];// make a copy of the input arrayvar copyArray = originalArray.slice(0);     
// first loop goes over every elementfor (var i = 0; i < originalArray.length; i++) {     
var count = 0;// loop over every element in the copy and see if it's the samefor (var w = 0; w < copyArray.length; w++) {if (originalArray[i] == copyArray[w]) {// increase amount of times duplicate is foundcount++;// sets item to undefineddelete copyArray[w];}}     
if (count > 0) {var a = new Object();a.value = originalArray[i];a.count = count;compressed.push(a);}}     
return compressed;};    
// It should go something like this:    
var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");var newArray = countArray(testArray);console.log(newArray);

惊讶的是,这个问题仍然没有添加最新的语法,添加我的2美分。

假设我们有一个对象数组arrObj,我们想在其中搜索obj。

Array.prototype.indexOf->(返回索引或-1)通常用于查找数组中元素的索引。这也可以用于搜索对象,但只有在传递对同一对象的引用时才有效。

let obj = { name: 'Sumer', age: 36 };let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];

console.log(arrObj.indexOf(obj));// 0console.log(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1
console.log([1, 3, 5, 2].indexOf(2)); //3

Array.prototype.包括->(返回真正虚假

console.log(arrObj.includes(obj));  //trueconsole.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false
console.log([1, 3, 5, 2].includes(2)); //true

Array.prototype.找到->(接受回调,返回第一个值/对象,在CB中返回true)。

console.log(arrObj.find(e => e.age > 40));  //{ name: 'Kishor', age: 46 }console.log(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }
console.log([1, 3, 5, 2].find(e => e > 2)); //3

Array.prototype.查找索引->(接受回调,返回第一个值/对象的索引,在CB中返回true)。

console.log(arrObj.findIndex(e => e.age > 40));  //1console.log(arrObj.findIndex(e => e.age > 40)); //1
console.log([1, 3, 5, 2].findIndex(e => e > 2)); //1

由于findIndex接受回调,我们可以通过创造性地设置true条件从数组中获取任何对象(即使我们没有引用)。

这个需求的简单解决方案是使用find()

如果你有像下面这样的对象数组,

var users = [{id: "101", name: "Choose one..."},{id: "102", name: "shilpa"},{id: "103", name: "anita"},{id: "104", name: "admin"},{id: "105", name: "user"}];

然后你可以检查具有你的值的对象是否已经存在:

let data = users.find(object => object['id'] === '104');

如果data为null,则没有admin,否则它将返回现有对象,如:

{id: "104", name: "admin"}

然后您可以在数组中找到该对象的索引并使用代码替换该对象:

let indexToUpdate = users.indexOf(data);let newObject = {id: "104", name: "customer"};users[indexToUpdate] = newObject;//your new objectconsole.log(users);

您将获得如下值:

[{id: "101", name: "Choose one..."},{id: "102", name: "shilpa"},{id: "103", name: "anita"},{id: "104", name: "customer"},{id: "105", name: "user"}];

性能

今天2020.01.07我在Chromev78.0.0,Safariv13.0.4和Firefox v71.0.0上对15个选定的解决方案进行了MacO HighSierra 10.13.6测试。结论

  • 基于JSONSet和令人惊讶的find(K、N、O)的解决方案在所有浏览器上都是最慢的
  • es6includes(F)仅在chrome上快速
  • 基于for(C, D)和indexOf(G, H)的解决方案在小型和大型数组的所有浏览器上都非常快,因此它们可能是高效解决方案的最佳选择
  • 循环过程中索引下降的解,(B)较慢可能是因为cpu缓存正常的方式。
  • 当搜索到的元素位于数组长度的66%位置时,我也对大数组进行了测试,基于for(C, D, E)的解决方案给出了类似的结果(~630行/秒-但Safari和Firefox上的E比C和D慢10-20%)

搜索结果

在此处输入图片描述

详情

我执行了2个测试用例:对于具有10个元素的数组,以及具有1百万个元素的数组。在这两种情况下,我们都将搜索元素放在数组中间。

let log = (name,f) => console.log(`${name}: 3-${f(arr,'s10')}  's7'-${f(arr,'s7')}  6-${f(arr,6)} 's3'-${f(arr,'s3')}`)
let arr = [1,2,3,4,5,'s6','s7','s8','s9','s10'];//arr = new Array(1000000).fill(123); arr[500000]=7;
function A(a, val) {var i = -1;var n = a.length;while (i++<n) {if (a[i] === val) {return true;}}return false;}
function B(a, val) {var i = a.length;while (i--) {if (a[i] === val) {return true;}}return false;}
function C(a, val) {for (var i = 0; i < a.length; i++) {if (a[i] === val) return true;}return false;}
function D(a,val){var len = a.length;for(var i = 0 ; i < len;i++){if(a[i] === val) return true;}return false;}
function E(a, val){var n = a.length-1;var t = n/2;for (var i = 0; i <= t; i++) {if (a[i] === val || a[n-i] === val) return true;}return false;}
function F(a,val) {return a.includes(val);}
function G(a,val) {return a.indexOf(val)>=0;}
function H(a,val) {return !!~a.indexOf(val);}
function I(a, val) {return a.findIndex(x=> x==val)>=0;}
function J(a,val) {return a.some(x=> x===val);}
function K(a, val) {const s = JSON.stringify(val);return a.some(x => JSON.stringify(x) === s);}
function L(a,val) {return !a.every(x=> x!==val);}
function M(a, val) {return !!a.find(x=> x==val);}
function N(a,val) {return a.filter(x=>x===val).length > 0;}
function O(a, val) {return new Set(a).has(val);}
log('A',A);log('B',B);log('C',C);log('D',D);log('E',E);log('F',F);log('G',G);log('H',H);log('I',I);log('J',J);log('K',K);log('L',L);log('M',M);log('N',N);log('O',O);
This shippet only presents functions used in performance tests - it not perform tests itself!

Array small - 10 elements

You can perform tests in your machine HERE

enter image description here

Array big - 1.000.000 elements

You can perform tests in your machine HERE

enter image description here

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

function filterByValue(array, string) {return array.filter(o =>Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase())));}
const arrayOfObject = [{name: 'Paul',country: 'Canada',}, {name: 'Lea',country: 'Italy',}, {name: 'John',country: 'Italy'}];
console.log(filterByValue(arrayOfObject, 'lea')); // [{name: 'Lea', country: 'Italy'}]console.log(filterByValue(arrayOfObject, 'ita')); // [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]

您还可以按特定键进行过滤,例如。

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

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

希望对你有帮助。

将唯一项添加到另一个列表

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 playListaddTrack = track => {if(playlistTracks.find(savedTrack => savedTrack.id === track.id)) {return;}playlistTracks.push(track);
this.setState({playlistTracks})};

使用indexOf()

您可以使用indexOf()方法来检查给定的值或元素是否存在于数组中。如果找到,indexOf()方法返回数组中元素的索引,如果未找到,则返回-1。让我们看一下以下示例:

var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"];var a = "Mango";checkArray(a, fruits);

function checkArray(a, fruits) {// Check if a value exists in the fruits arrayif (fruits.indexOf(a) !== -1) {return document.write("true");} else {return document.write("false");}}

使用包括()方法

ES6引入了包括()方法来非常轻松地执行此任务。但是,此方法仅返回true或false而不是索引号:

var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"];alert(fruits.includes("Banana")); // Outputs: truealert(fruits.includes("Coconut")); // Outputs: falsealert(fruits.includes("Orange")); // Outputs: truealert(fruits.includes("Cherry")); // Outputs: false

有关更多信息,请查看这里

这可能是一个详细和简单解决方案。

//plain arrayvar arr = ['a', 'b', 'c'];var check = arr.includes('a');console.log(check); //returns trueif (check){// value exists in array//write some codes}
// array with objectsvar arr = [{x:'a', y:'b'},{x:'p', y:'q'}];
// if you want to check if x:'p' exists in arrvar check = arr.filter(function (elm){if (elm.x == 'p'){return elm; // returns length = 1 (object exists in array)}});
// or y:'q' exists in arrvar check = arr.filter(function (elm){if (elm.y == 'q'){return elm; // returns length = 1 (object exists in array)}});
// if you want to check, if the entire object {x:'p', y:'q'} exists in arrvar check = arr.filter(function (elm){if (elm.x == 'p' && elm.y == 'q'){return elm; // returns length = 1 (object exists in array)}});
// in all casesconsole.log(check.length); // returns 1
if (check.length > 0){// returns true// object exists in array//write some codes}

使用Array.prototype.includes例如:

const fruits = ['coconut', 'banana', 'apple']
const doesFruitsHaveCoconut = fruits.includes('coconut')// true
console.log(doesFruitsHaveCoconut)

也许从MDN读这个留档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

您可以使用findIndex函数来检查数组是否具有特定值。

arrObj.findIndex(obj => obj === comparedValue) !== -1;

如果arrObj包含comparedValue,则返回true,否则返回false。

使用RegExp:

console.log(new RegExp('26242').test(['23525', '26242', '25272'].join(''))) // true

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

Array.prototype.some()

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

const array = [1, 2, 3, 4, 5];
// checks whether an element is evenconst 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

有几个方法可以轻松实现(includessomefindfindIndex

const array = [1, 2, 3, 4, 5, 6, 7];
console.log(array.includes(3));//includes() determines whether an array includes a certain value among its entries
console.log(array.some(x => x === 3));//some() tests if at least one element in the array passes the test implemented by the provided function
console.log(array.find(x => x === 3) ? true : false);//find() returns the value of the first element in the provided array that satisfies the provided testing function
console.log(array.findIndex(x => x === 3) > -1);//findIndex() returns the index of the first element in the array that satisfies the provided testing function, else returning -1.

如果你只是想检查一个值是否包含在集合中,使用Set会更合适,因为Arrays可以有重复的值,而Sets不能。此外,用set.has替换array.includes可以将性能从O(n2)提高到O(n)。当你必须为同一个设置查找多个值时,这将很有用。所以如果你只是要查找一个值,使用set.has没有好处,你可以只使用array.includes

创建了一个jsBench演示,您可以运行它来检查性能。

测试执行的屏幕截图:

输入图片描述

在Javascript中查找数组是否包含值的最快方法是:

function existsInArrayForIgnoreDataType(arr, targetElem) {for (let i = 0; i < arr.length; i++) {if (arr[i] == targetElem) return true}return false}

你可以找到我做的完整研究这里

有几种方法可以找到答案。您可以使用内置的数组方法。最突出使用的是数组查找方法。

const arr1 = [1, 2, 3, 4, 5]const result = arr1.find(ele => ele === 4)console.log(result) //4
const result2 = arr1.find(ele => ele === 6)console.log(result2) //undefined/*If the element is present inside the arraythen it will return the first element thatsatisfies the given condition. Otherwiseundefined will return.*/