如何检查数组是否包含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.

回答

目前的浏览器都有Array#includes,这不正是那个,得到广泛支持,并具有填充工具旧版本浏览器.

> ['joe', 'jane', 'mary'].includes('jane');
true

您也可以使用Array#indexOf,这不是直接的,但不要求Polyfills用于过时的浏览器.

jQuery提供$.inArray,功能相当于Array#indexOf.

underscore.js,一个JavaScript实用程序库,提供_.contains(list, value)别名_.include(list, value),如果传递了JavaScript数组,它们都在内部使用indexOf.

其他一些框架提供了类似的方法:

  • Dojo工具包: dojo.indexOf(array, value, [fromIndex, findLast])
  • 原型: array.indexOf(value)
  • MooTools的: array.indexOf(value)
  • MochiKit: findValue(array, value)
  • MS Ajax: array.indexOf(value)
  • 分机: Ext.Array.contains(array, value)
  • Lodash 🙁 先前_.includes(array, value, [from])_.contains4.0.0)
  • ECMAScript 2016: R.includes(value, array)

请注意,某些框架将此实现为函数,而其他框架则将该函数添加到数组原型中.

  • `inArray`是一个返回元素索引的函数的可怕名称,如果它不存在则是`-1`.我希望返回一个布尔值.
  • 如果您使用的是良好的浏览器,则可以使用`array.indexOf(object)!= -1`
  • MooTools还有Array.contains,它返回一个布尔值,这听起来像是真正的问题.
  • prototype还有一个返回布尔值的`Array.include`
  • 另外,不要单独使用indexOf作为条件,因为第一个元素将返回0并将被评估为falsy
  • @IulianOnofrei:不,在[1,2,3] == true`中为'2,但在[3,4,5]中= 5 = = false.为什么?因为JavaScripts中的数组就像常规对象一样,所以数组中的"2"实际上只意味着定义了`array [2]`.请注意,这种行为仍然有用,因为JavaScript数组可能很稀疏:`2 in [1,2,,3] == false`
  • `array.includes(foo)`不支持对象.我不确定为什么这是接受的答案,因为它被问到*如何检查数组是否包含JavaScript中的对象?*
  • @Tim 我猜它返回 -1 以否定 0 被视为虚假的机会
  • 现在是 2016 年,我仍然无法在“非原始”类型上正确使用 .include 和 .indexOf。
  • “广泛”具有误导性,因为 IE 11 不支持它
  • 这个答案有很多争议,但问题是关于数组中的对象的,这是行不通的。

更新:正如@orip在评论中提到的,链接的基准测试是在2008年完成的,因此结果可能与现代浏览器无关.但是,你可能还需要这个来支持非现代浏览器,因为它们可能还没有更新过.总是为自己测试.

正如其他人所说,通过数组的迭代可能是最好的方法,但已经证明,减少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)); // => true
alert([1, 2, 3].contains('2')); // => false
  • 但要小心:http://stackoverflow.com/questions/237104/javascript-array-containsobj/1342312#1342312
  • "经证实"是一个强有力的词.JS引擎不断改进,3年前测量的执行时间非常过时.
  • @Damir - 我同意.也许更改样本以使用indexOf(如果可用),这样人们盲目地复制粘贴此代码将获得最佳性能.

indexOf 也许,但它是"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),如果你想作为一个快速谷歌搜索发现(例如,这一个).

  • [IE9现在支持这个](http://stackoverflow.com/questions/3629183/why-doesnt-indexof-work-on-an-array-ie8)

ECMAScript 7介绍Array.prototype.includes.

它可以像这样使用:

[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比较了使用SameValueZero平等算法.这意味着您可以检测数组是否包含NaN:

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

也不像indexOf,includes不跳过缺失的索引:

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

目前它仍然是草稿,但可以填充以使其适用于所有浏览器.

  • IE和Microsfot Edge不支持(2015)(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)
  • 同样相关的,[ES7 兼容性表](http://kangax.github.io/compat-table/esnext/#test-Array.prototype.includes)(看起来chrome现在支持它)

3是值,true是数组.它返回false3:

const array = [1, 2, 3, 4]
  • "〜"是一个运算符,它从一个数字中取消,反转和减1.indexOf如果失败则返回-1,因此"〜"将-1变为"0".使用"!!" 将数字变成波尔语(!! 0 === false)
  • 这部分我不明白"!!〜".我认为这在IE8中不起作用,因为IE8不支持Array对象上的indexOf().
  • 我称缺乏关于布尔运算符不专业的影响的知识.但我同意可读代码的价值,我肯定会将其包含在一个明确标记的函数中.这正是大多数主流JS框架所做的.

顶部答案假设基本类型但如果您想要查明数组是否包含具有某些特征的对象,则Array.prototype.some()是一个非常优雅的解决方案:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]
items.some(item => item.a === '3')  // returns true
items.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支持表

  • 截至今天,2018 年 9 月,Array.prototype.some() 已完全支持:[caniuse.com 支持表](http://kangax.github.io/compat-table/es5/#test-Array_methods_Array.prototype.some_a_href =_https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some_title=_MDN_documentation_img_src=_../mdn.png_alt=_MDN_(Mozilla_Development_Network)_logo_width=_15_height=_13_/_ /a_nbsp;)
  • 在 Node &gt;=8.10 中为 AWS Node.js Lambda 工作,所以这很棒。非常干净和简单的解决方案!
  • @jamess 它可能得到很好的支持,但请记住,此示例中的“箭头函数”并没有得到很好的支持。有关更多详细信息,请参见此处:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Browser_compatibility

这是一个JavaScript 1.6兼容的实现Array.indexOf:

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;
};
}
  • 它们并不相同.`[] .indexOf`是`Array.prototype.indexOf`的简写.我们偏执防御Javascript程序员不惜一切代价避免扩展原生原型.
  • @alex yes` [] .indexOf === Array.prototype.indexOf`(在FireBug中试用),但反过来说`[] .indexOf!== Array.indexOf`.
  • `[].indexOf` 不是创建一个新数组然后访问`indexOf`,而`Array.prototype.indexOf` 只是直接访问原型吗?

使用:

function isInArray(array, search)
{
return array.indexOf(search) >= 0;
}
// Usage
if(isInArray(my_array, "my_value"))
{
//...
}
  • `x?true:false`通常是多余的.是这里.
  • `array.indexOf(search)> = 0`已经是一个布尔值.只需`return array.indexOf(search)> = 0`.
  • 从字面上看,javascript 中的任何构造都可以返回

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

如果您不需要担心与页面上运行的其他JavaScript的兼容性,请继续使用,否则,我建议使用更笨拙但更安全的独立功能解决方案.

  • 我不同意.出于这个原因,不应将for-in循环用于数组.当使用一个流行的js库时,使用for-in循环将会中断

表现

今天 2020.01.07 我在 Chrome v78.0.0、Safari v13.0.4 和 Firefox v71.0.0 的 MacOs HighSierra 10.13.6 上对 15 个选择的解决方案进行了测试。结论

  • 基于JSON,Set令人惊讶的是find(K,N,O) 的解决方案在所有浏览器上都是最慢的
  • es6 includes(F) 仅在 chrome 上快
  • 基于for(C,D) 和indexOf(G,H)的解决方案在小型和大型阵列的所有浏览器上都非常快,因此它们可能是高效解决方案的最佳选择
  • 循环期间索引减少的解决方案,(B) 较慢可能是因为CPU 缓存的工作方式。
  • 当搜索元素位于数组长度的 66% 位置时,我还对大数组进行了测试,基于for(C,D,E) 的解决方案给出了类似的结果(~630 ops/sec - 但 safari 和 firefox 上的 E 为 10-比 C 和 D 慢 20%)

结果

细节

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

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!

数组小 - 10 个元素

您可以在这里在您的机器上执行测试

数组大 - 1.000.000 个元素

您可以在这里在您的机器上执行测试


开箱即用,如果您多次进行此调用,使用关联数组 Map使用散列函数进行查找会大大提高效率.

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


一内胆:

function contains(arr, x) {
return arr.filter(function(elem) { return elem == x }).length > 0;
}
  • `array.filter(e => e == x).length> 0`相当于`array.some(e => e == x)`但是`some`效率更高

我使用以下内容:

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

function contains(a, obj) {
return a.some(function(element){return element == obj;})
}

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


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

2015年

虽然新方法包含非常好,但现在支持基本上为零.

很长一段时间我一直想着替换慢的indexOf/lastIndexOf函数.

已找到一种高效的方式,查看最佳答案.从那些我选择contains@Damir Zekic发布的功能应该是最快的.但它也表示基准测试是从2008年开始的,因此已经过时了.

我也喜欢whilefor,但不具体原因我结束了编写函数for循环.也可以用a来完成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]===b
if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
}
return -1
}
//Usage
bidirectionalIndexOf(array,'value');

性能测试

http://jsperf.com/bidirectionalindexof

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

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

我希望你也发现这个有趣并测试性能.

注意:正如您所看到的,我稍微修改了contains函数以反映indexOf和lastIndexOf输出(因此基本上true使用indexfalsewith -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]===b
if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
}
return -1
},writable:false, enumerable:false});
// Usage
array.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
}
// Usage
bidirectionalIndexOf(array,'value');

这怎么可能?

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

下面是一个复杂的示例,每次迭代执行三次检查,但这只能通过更长的计算才能实现,这会导致代码速度变慢.

http://jsperf.com/bidirectionalindexof/2


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 1.6或更高版本(Firefox 1.5或更高版本),则可以使用Array.indexOf.否则,我认为你最终会得到类似于原始代码的东西.


如果您反复检查数组中是否存在对象,您应该查看

  1. 通过在数组中执行插入排序来保持数组始终排序(将新对象放在正确的位置)
  2. 将对象更新为删除+排序插入操作和
  3. 在您的中使用二进制搜索查找contains(a, obj).
  • 或者如果可能的话,完全停止使用数组,而是使用Object作为字典,如MattMcKnight和ninjagecko所建议的那样.

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

/*
* @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");          //true
a.inArray("foo");            //false
a.inArray("foo", true);      //true - search by keys
a.inArray({three: "third"}); //true
var b = ["one", "two", "three", "four", {foo: 'val'}];
b.inArray("one");         //true
b.inArray('foo');         //false
b.inArray({foo: 'val'})   //true
b.inArray("{foo: 'val'}") //false
var c = "String";
c.inArray("S");        //true
c.inArray("s");        //false
c.inArray("2", true);  //true
c.inArray("20", true); //false

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

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
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;
};
}

用法:

为什么要使用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


contains使用性能优化更新了函数.感谢itinance指出它.

  • @itinance 好点。根据您的建议更新了 `includes` 功能。我已经用我的函数运行了 jsperf。它比 lodash 的包含慢 5 倍。尽管 lodash 不按值进行比较,并且在 `[{a: 1}]` 中找不到 `{a: 1}`。不知道有没有图书馆这样做。但我很好奇是否有任何更高效而不是疯狂复杂的方式来做到这一点。
  • @HereticMonkey, true. That's why I added the `sort-keys` note at the bottom

可以使用具有“has()”方法的Set:

function contains(arr, obj) {
var proxy = new Set(arr);
if (proxy.has(obj))
return true;
else
return false;
}
var arr = ['Happy', 'New', 'Year'];
console.log(contains(arr, 'Happy'));
  • 我认为 `return proxy.has(obj)` 比两行 if-else 语句要简洁得多

使用lodash的一些功能.

它简洁,准确,并具有很好的跨平台支持.

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

要求:推荐最简洁有效的方法来确定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)

虽然这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来"冻结"一个数组并将this._cache中的哈希表存储在两行中,但是如果你以后选择编辑你的数组会产生错误的结果.JavaScript没有足够的钩子.让你保持这种状态,例如Python不同.)


此要求的简单解决方案是使用 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');

如果数据为空,则没有管理员,否则它将返回现有对象,如下所示。

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

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

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

您将获得如下价值

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

希望这会帮助任何人。


ECMAScript 6有一个关于find的优雅提议.

这是关于它的MDN文档.

find功能就像这样.

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 found
console.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;
}
});
}

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

假设我们有对象数组 arrObj 并且我们想在其中搜索 obj 。

数组.原型。indexOf -> (返回index 或 -1)通常用于查找数组中元素的索引。这也可用于搜索对象,但仅当您传递对同一对象的引用时才有效。

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

数组.原型。包括-> (返回truefalse

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

数组.原型。find ->(接受回调,返回第一个在 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

数组.原型。findIndex ->(接受回调,返回第一个在 CB 中返回 true 的值/对象的索引)。

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

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


使用:

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

演示

要确切了解此时的tilde ~操作,请参阅此问题当代码在表达式之前时,代字号会做什么?.

  • 这已经发布[年和半年前](http://stackoverflow.com/a/9849276/447356)无需重复.
  • 实际上,它还没有发布.不是作为答案,而是作为对答案的评论,即便如此,它也不清楚和简洁.感谢发布它,Mina Gabriel.

绝不是最好的,但我只是变得有创意并添加到曲目中。

不要使用这个

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 1
console.log(['one', 'two'].exists('two'));
// Outputs -1
console.log(['one', 'two'].exists('three'));
console.log(['one', 'two', 'three', 'four'].exists('four'));

它有一个参数:一个对象数组。数组中的每个对象都有两个整数属性,用 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);

    function countArray(originalArray) {
var compressed = [];
// make a copy of the input array
var copyArray = originalArray.slice(0);
// first loop goes over every element
for (var i = 0; i < originalArray.length; i++) {
var count = 0;
// loop over every element in the copy and see if it's the same
for (var w = 0; w < copyArray.length; w++) {
if (originalArray[i] == copyArray[w]) {
// increase amount of times duplicate is found
count++;
// sets item to undefined
delete 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);

以下是如何原型做它:

/**
*  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;
}

另请参阅此处了解它们如何连接。


你也可以使用这个技巧:

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

好的,您只需优化代码即可获得结果!

有很多方法可以做到这一点越来越好,但我只是想获取您的模式并将其应用于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;
}

  1. 要么使用Array.indexOf(Object).
  2. 使用 ECMA 7 可以使用Array.includes(Object).
  3. 希望这可以帮助!


使用 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 array
if (fruits.indexOf(a) !== -1) {
return document.write("true");
} else {
return document.write("false");
}
}

使用 include() 方法

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

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

如需进一步参考,请点击此处


使用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


以上是如何检查数组是否包含JavaScript中的对象?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>