如何简单直接地找到满足某些条件的对象数组中的索引?
例如,给定以下输入:
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
)?
我认为您可以使用map函数在一行中解决它:
const pos = myArray.map(e => e.hello).indexOf('stevie');
Array.prototype.map()
方法。 - AlbertEngelBArray.prototype.findIndex 在除了 IE(非 Edge 版本)之外的所有浏览器中都支持。但是提供的polyfill很好用。
var indexOfStevie = myArray.findIndex(i => i.hello === "stevie");
使用map的解决方案是可以的。但是你每次搜索时都要遍历整个数组。这对于findIndex来说只有在找到匹配项后才停止迭代,所以这是最坏情况。
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')
var idx = myArray.reduce( function( cur, val, index ){
if( val.hello === "stevie" && cur === -1 ) {
return index;
}
return cur;
}, -1 );
我喜欢Pablo的答案,但是Array#indexOf和Array#map在所有浏览器上都不起作用。如果原生代码可用,Underscore将使用它,但也有备选方案。此外,它还具有pluck方法,可以完全执行Pablo的匿名映射方法。
var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();
chain
is superfluous here. _.pluck(myArray, 'hello').indexOf('stevie')
- Steve Bennett或者原型化它:
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");
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;
};
- Adamif (typeof property === 'string' || typeof property === 'number' || typeof property === 'boolean') return oldIndexOf(property, value);
的东西。这是因为这些类型是不可变的。我还会添加第三个参数以启用必要时回退到本机方法的功能。 - Claudia虽然其他答案大多数都是正确的,但有时候,在你将要使用它的地方编写一个简短而简单的函数,可能是最好的选择。
// 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');
这取决于你认为重要的是什么。使用一行代码或在某个地方放置通用解决方案可能会节省代码行数并非常巧妙,但有时候最好只是说:“我是这样做的”,而不是让未来的开发人员在反向工程上多花时间。特别是当你像你提问时自认为是“新手”的时候。
for-of
循环吗? - Douglas Gaskellvar hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var qazCLONE = { // new object instance and same structure
hello: 'stevie',
foo: 'baz'
}
var myArray = [hello,qaz];
myArray.indexOf(qaz) // should return 1
myArray.indexOf(qazCLONE) // should return -1
myArray.indexOf('stevie','hello')
/*****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
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);
}
};
hello
和qaz
吗? - Arminvar elementPos = array.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor); var objectFound = array[elementPos];
- Rick