Javascript 对象数组中的 indexOf 方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8668174/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
indexOf method in an object array?
提问by Antonio Laguna
What's the best method to get the index of an array which contains objects?
获取包含对象的数组索引的最佳方法是什么?
Imagine this scenario:
想象一下这个场景:
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello,qaz);
Now I would like to have the indexOf
the object which hello
property is 'stevie'
which, in this example, would be 1
.
现在我想要属性是indexOf
的对象,在这个例子中,将是.hello
'stevie'
1
I'm pretty newbie with JavaScript and I don't know if there is a simple method or if I should build my own function to do that.
我是 JavaScript 的新手,我不知道是否有一个简单的方法,或者我是否应该构建自己的函数来做到这一点。
回答by Pablo Francisco Pérez Hidalgo
回答by Joe
Array.prototype.findIndexis supported in all browsers other than IE (non-edge). But the polyfillprovided is nice.
Array.prototype.findIndex在除 IE(非边缘)之外的所有浏览器中都受支持。但是提供的polyfill很好。
var indexOfStevie = myArray.findIndex(i => i.hello === "stevie");
The solution with map is okay. But you are iterating over the entire array every search. That is only the worst case for findIndexwhich stops iterating once a match is found.
带地图的解决方案没问题。但是您每次搜索都在遍历整个数组。这只是findIndex的最坏情况,一旦找到匹配项,它就会停止迭代。
var searchTerm = "stevie",
index = -1;
for(var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i].hello === searchTerm) {
index = i;
break;
}
}
or as a function:
或作为一个函数:
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
Just some notes:
只是一些注意事项:
- Don't use for...in loops on arrays
- Be sure to break out of the loop or return out of the function once you've found your "needle"
- Be careful with object equality
- 不要在数组上使用 for...in 循环
- 一旦你找到你的“针”,一定要跳出循环或返回函数
- 小心对象相等
For example,
例如,
var a = {obj: 0};
var b = [a];
b.indexOf({obj: 0}); // -1 not found
回答by Steve Bennett
In ES2015, this is pretty easy:
在 ES2015 中,这很容易:
myArray.map(x => x.hello).indexOf('stevie')
or, probably with better performance for larger arrays:
或者,对于较大的阵列可能具有更好的性能:
myArray.findIndex(x => x.hello === 'stevie')
回答by Esailija
var idx = myArray.reduce( function( cur, val, index ){
if( val.hello === "stevie" && cur === -1 ) {
return index;
}
return cur;
}, -1 );
回答by tandrewnichols
I like Pablo's answer, but Array#indexOf and Array#map don't work on all browsers. Underscore will use native code if it's available, but has fallbacks as well. Plus it has the pluck method for doing exactly what Pablo's anonymous map method does.
我喜欢 Pablo 的回答,但 Array#indexOf 和 Array#map 不适用于所有浏览器。如果可用,下划线将使用本机代码,但也有回退。此外,它还具有 pluck 方法,可以完全执行 Pablo 的匿名映射方法所做的工作。
var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();
回答by Nathan Zaetta
Or prototype it :
或者原型它:
Array.prototype.indexOfObject = function arrayObjectIndexOf(property, value) {
for (var i = 0, len = this.length; i < len; i++) {
if (this[i][property] === value) return i;
}
return -1;
}
myArr.indexOfObject("name", "stevie");
回答by Abdennour TOUMI
Brief
简短的
myArray.indexOf('stevie','hello')
Use Cases :
用例 :
/*****NORMAL****/
[2,4,5].indexOf(4) ;//OUTPUT 1
/****COMPLEX*****/
[{slm:2},{slm:4},{slm:5}].indexOf(4,'slm');//OUTPUT 1
//OR
[{slm:2},{slm:4},{slm:5}].indexOf(4,function(e,i){
return e.slm;
});//OUTPUT 1
/***MORE Complex**/
[{slm:{salat:2}},{slm:{salat:4}},{slm:{salat:5}}].indexOf(4,function(e,i){
return e.slm.salat;
});//OUTPUT 1
API :
应用程序接口:
Array.prototype.indexOfOld=Array.prototype.indexOf
Array.prototype.indexOf=function(e,fn){
if(!fn){return this.indexOfOld(e)}
else{
if(typeof fn ==='string'){var att=fn;fn=function(e){return e[att];}}
return this.map(fn).indexOfOld(e);
}
};
回答by Uniphonic
I did some performance testing of various answers here, which anyone can run them self:
我在这里对各种答案进行了一些性能测试,任何人都可以自己运行它们:
https://jsperf.com/find-index-of-object-in-array-by-contents
https://jsperf.com/find-index-of-object-in-array-by-contents
Based on my initial tests in Chrome, the following method (using a for loop set up inside a prototype) is the fastest:
根据我在 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");
This code is a slightly modified version of Nathan Zaetta's answer.
此代码是 Nathan Zaetta 答案的略微修改版本。
In the performance benchmarks I tried it with both the target being in the middle (index 500) and very end (index 999) of a 1000 object array, and even if I put the target in as the very last item in the array (meaning that it it has to loop through every single item in the array before it's found) it still ends up the fastest.
在性能基准测试中,我尝试将目标放在 1000 个对象数组的中间(索引 500)和最后(索引 999),即使我将目标作为数组中的最后一项(意思是它必须在找到之前遍历数组中的每个项目)它仍然是最快的。
This solution also has the benefit of being one of the most terse for repeatedly executing, since only the last line needs to be repeated:
此解决方案还具有作为重复执行最简洁的解决方案之一的好处,因为只需要重复最后一行:
myArray.indexOfObject("hello", "stevie");
回答by John Klimov
I compared several methods and received a result with the fastest way to solve this problem. It's a for
loop. It's 5+ times faster than any other method.
我比较了几种方法,得到了解决这个问题的最快方法的结果。这是一个for
循环。它比任何其他方法快 5 倍以上。
Here is the test's page: https://jsbench.me/9hjewv6a98
这是测试的页面:https: //jsbench.me/9hjewv6a98
回答by SpiRail
While, most other answers here are valid. Sometimes, it's best to just make a short simple function near where you will use it.
虽然,这里的大多数其他答案都是有效的。有时,最好在您将使用它的地方附近制作一个简短的简单函数。
// indexOf wrapper for the list of objects
function indexOfbyKey(obj_list, key, value) {
for (index in obj_list) {
if (obj_list[index][key] === value) return index;
}
return -1;
}
// Find the string in the list (default -1)
var test1 = indexOfbyKey(object_list, 'name', 'Stevie');
var test2 = indexOfbyKey(object_list, 'last_name', 'some other name');
It depends on what is important to you. It might save lines of code and be very clever to use a one-liner, or to put a generic solution somewhere that covers various edge cases. But sometimes it's better to just say: "here I did it like this" rather than leave future developers to have extra reverse engineering work. Especially if you consider yourself "a newbie" like in your question.
这取决于什么对你很重要。使用单行代码或将通用解决方案放在涵盖各种边缘情况的某处可能会节省代码行并且非常聪明。但有时最好只是说:“我就是这样做的”,而不是让未来的开发人员进行额外的逆向工程工作。特别是如果您认为自己是“新手”,就像您的问题一样。