我怎样才能简单直接地找到满足某些条件的对象数组中的索引?
例如,给定这个输入:
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello, qaz);
我如何搜索myArray找到其hello属性等于'stevie'的元素的索引(在这种情况下,结果应该是1)?
我怎样才能简单直接地找到满足某些条件的对象数组中的索引?
例如,给定这个输入:
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello, qaz);
我如何搜索myArray找到其hello属性等于'stevie'的元素的索引(在这种情况下,结果应该是1)?
当前回答
array.filter(function(item, indx, arr){ return(item.hello === 'stevie'); })[0];
小心[0]。
在安东尼奥·拉古纳的回答中使用reduce是恰当的。
抱歉这么简短……
其他回答
Array.prototype.findIndex在除IE(非边缘)之外的所有浏览器中都支持。但是提供的填充材料很好。
var indexOfStevie = myArray.findIndex(i => i.hello === "stevie");
map的解决方案是可以的。但每次搜索都要遍历整个数组。这只是findIndex的最坏情况,它一旦找到匹配项就会停止迭代。
没有一个简洁的方法(当开发者不得不担心IE8时),但这里有一个常见的解决方案:
var searchTerm = "stevie",
index = -1;
for(var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i].hello === searchTerm) {
index = i;
break;
}
}
或作为一个函数:
function arrayObjectIndexOf(myArray, searchTerm, property) {
for(var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i][property] === searchTerm) return i;
}
return -1;
}
arrayObjectIndexOf(arr, "stevie", "hello"); // 1
只是一些注释:
不要用于…在数组的循环中 一旦找到“指针”,请确保跳出循环或返回函数。 注意对象相等性
例如,
var a = {obj: 0};
var b = [a];
b.indexOf({obj: 0}); // -1 not found
在ES2015中,这很简单:
myArray.map(x => x.hello).indexOf('stevie')
或者,更大的数组可能会有更好的性能:
myArray.findIndex(x => x.hello === 'stevie')
我比较了几种方法,得到了一个最快解决这个问题的结果。这是一个for循环。它比其他方法快5倍以上。
下面是测试页面:https://jsbench.me/9hjewv6a98
如果你只是对这个职位感兴趣,请参阅@Pablo的答案。
pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');
然而,如果你希望找到元素(例如,如果你正在考虑做这样的myArray[pos]),有一个更有效的单行方法来做,使用过滤器。
element = myArray.filter((e) => e.hello === 'stevie')[0];
参见性能结果(~ +42% ops/sec): http://jsbench.github.io/#7fa01f89a5dc5cc3bee79abfde80cdb3
我在这里对各种答案做了一些性能测试,任何人都可以自己运行:
https://jsperf.com/find-index-of-object-in-array-by-contents
根据我在Chrome中的初始测试,以下方法(使用原型内部设置的for循环)是最快的:
Array.prototype.indexOfObject = function (property, value) {
for (var i = 0, len = this.length; i < len; i++) {
if (this[i][property] === value) return i;
}
return -1;
}
myArray.indexOfObject("hello", "stevie");
这段代码是对Nathan Zaetta的答案稍加修改的版本。
在性能基准测试中,我尝试将目标放在1000对象数组的中间(索引500)和末尾(索引999),即使我将目标放在数组中的最后一项(意味着它必须循环遍历数组中的每一项才能找到),它仍然是最快的。
这个解决方案还有一个好处,就是对于重复执行来说是最简洁的,因为只需要重复最后一行:
myArray.indexOfObject("hello", "stevie");