获取包含对象的数组的索引的最佳方法是什么?
想象一下这种情况:
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello,qaz);
现在我希望indexOf
hello
属性为'stevie'
的对象,在此示例中为1
。
我是JavaScript的新手,我不知道是否有一个简单的方法,或者我是否应该构建自己的函数来做到这一点。
答案 0 :(得分:884)
我认为你可以使用map函数在一行中解决它:
pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');
答案 1 :(得分:317)
Array.prototype.findIndex(非边缘)。但提供的polyfill很不错。
var indexOfStevie = myArray.findIndex(i => i.hello === "stevie");
带地图的解决方案没问题。但是你每次搜索都在迭代整个数组。这只是 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
答案 2 :(得分:107)
在ES2015中,这很简单:
myArray.map(x => x.hello).indexOf('stevie')
或者,对于更大的阵列可能具有更好的性能:
myArray.findIndex(x => x.hello === 'stevie')
答案 3 :(得分:25)
var idx = myArray.reduce( function( cur, val, index ){
if( val.hello === "stevie" && cur === -1 ) {
return index;
}
return cur;
}, -1 );
答案 4 :(得分:18)
我喜欢Pablo的回答,但是Array#indexOf和Array #map并不适用于所有浏览器。如果可用,Underscore将使用本机代码,但也会有后备。此外,它还具有完全符合Pablo匿名地图方法的方法。
var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();
答案 5 :(得分:15)
或原型:
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");
答案 6 :(得分:9)
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);
}
};
答案 7 :(得分:6)
我在这里对各种答案进行了一些性能测试,任何人都可以自己运行它们:
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");
答案 8 :(得分:5)
我比较了几种方法,并以最快的方式解决了这个问题。这是一个for
循环。它比任何其他方法快5倍。
以下是测试页面:https://jsbench.me/9hjewv6a98
答案 9 :(得分:4)
array.filter(function(item, indx, arr){ return(item.hello === 'stevie'); })[0];
注意[0]
。
在reduce
的答案中使用Antonio Laguna
是合适的。
道歉......
答案 10 :(得分:3)
如果您只想找到位置,请参阅@Pablo's answer。
pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');
但是,如果您期待找到元素(即如果您正在考虑做这样的事情myArray[pos]
),那么更高效的单行方法,使用filter
。
element = myArray.filter((e) => e.hello === 'stevie')[0];
查看性能结果(〜+ 42%ops / sec): http://jsbench.github.io/#7fa01f89a5dc5cc3bee79abfde80cdb3
答案 11 :(得分:3)
虽然这里的大多数其他答案都是有效的。有时,最好只在您将使用它的地方附近做一个简单的简单功能。
// 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');
这取决于对您来说重要的事情。它可以节省代码行,并且非常聪明地使用单行程序,或者在一个覆盖各种边缘情况的地方放置通用解决方案。但有时候只是说:“#34;在这里,我就这样做了#34;而不是让未来的开发人员进行额外的逆向工程工作。特别是如果你认为自己是一个新手&#34;喜欢你的问题。
答案 12 :(得分:3)
简单:
myArray.indexOf(myArray.filter(function(item) {
return item.hello == "stevie"
})[0])
答案 13 :(得分:3)
试试这个:
console.log(Object.keys({foo:"_0_", bar:"_1_"}).indexOf("bar"));
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
答案 14 :(得分:2)
使用ES6 findIndex
method,不使用lodash或任何其他库,您可以写:
function deepIndexOf(arr, obj) {
return arr.findIndex(function (cur) {
return Object.keys(obj).every(function (key) {
return obj[key] === cur[key];
});
});
}
这将比较对象的直接属性,但不会递归到属性中。
如果您的实施尚未提供findIndex
(大部分没有),您可以添加支持此搜索的轻量级填充:
function deepIndexOf(arr, obj) {
function findIndex = Array.prototype.findIndex || function (pred) {
for (let i = 0; i < this.length; ++i) {
if (pred.call(this, this[i], i)) {
return i;
}
}
return -1;
}
return findIndex.call(arr, function (cur) {
return Object.keys(obj).every(function (key) {
return obj[key] === cur[key];
});
});
}
(来自我对this dupe的回答)
答案 15 :(得分:2)
如果您的对象与您在数组中使用的对象相同,则您应该能够像使用字符串一样获取Object的索引。
var 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
答案 16 :(得分:2)
您基本上可以使用原生且方便的功能Array.prototype.findIndex()
:
如果数组中的元素满足提供的测试函数,则findIndex()方法返回数组中的索引。否则返回-1。
只需注意它在Internet Explorer,Opera和Safari上不受支持,但您可以使用以下链接中提供的Polyfill。
更多信息:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello, qaz);
var index = myArray.findIndex(function(element, index, array) {
if (element.hello === 'stevie') {
return true;
}
});
alert('stevie is at index: ' + index);
答案 17 :(得分:2)
@Monika Garg answer的使用者,您可以使用findIndex()
(对于未浏览的浏览器,有polyfill个。)
我看到有人低估了这个答案,我希望他们这样做是因为错误的语法,因为在我看来,这是最优雅的方式。
如果数组中的元素满足提供的测试函数,则findIndex()方法返回数组中的索引。否则返回-1。
例如:
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello,qaz);
var index = myArray.findIndex(function(element) {
return element.hello == 'stevie';
});
alert(index);
答案 18 :(得分:2)
_.findIndex
以下是这个例子
_.findIndex([{a:1},{a: 2,c:10},{a: 3}], {a:2,c:10}) //1
答案 19 :(得分:2)
我已经制作了一个通用函数来检查下面的代码&amp;适用于任何对象
function indexOfExt(list, item) {
var len = list.length;
for (var i = 0; i < len; i++) {
var keys = Object.keys(list[i]);
var flg = true;
for (var j = 0; j < keys.length; j++) {
var value = list[i][keys[j]];
if (item[keys[j]] !== value) {
flg = false;
}
}
if (flg == true) {
return i;
}
}
return -1;
}
var items = [{ "hello": 'world', "foo": 'bar' }];
var selectedItem = { "hello": 'world', "foo": 'bar' };
alert(items.indexOf(selectedItem));
alert(indexOfExt(items, selectedItem));
第一个警报将返回-1(表示未找到匹配)&amp;第二个警报将返回0(表示匹配找到)。
答案 20 :(得分:2)
请参阅此示例:http://jsfiddle.net/89C54/
for (i = 0; i < myArray.length; i++) {
if (myArray[i].hello === 'stevie') {
alert('position: ' + i);
return;
}
}
它开始计为零。
答案 21 :(得分:1)
这是在数组中找到对象索引的方法
var myArray = [{ hello: 'world',
foo: 'bar'
},{
hello: 'stevie',
foo: 'baz'
}];
for (i = 0; i < myArray.length; i++) {
if (myArray[i].hello === 'stevie') {
alert('position: ' + i);
return;
}
}
答案 22 :(得分:0)
您只需使用
即可
const someId = 2;
const array = [{id:1}, {id:2}, {id:3}];
const index = array.reduce((i, item, index) => item.id === someId ? index : i, -1);
alert('someId ' + someId + ' is at index ' + index);
&#13;
没有下划线,没有,只是减少。
答案 23 :(得分:0)
var hello = {hello: "world", foo: "bar"};
var qaz = {hello: "stevie", foo: "baz"};
var myArray = [];
myArray.push(hello,qaz);
function indexOfObject( arr, key, value ) {
var j = -1;
var result = arr.some(function(obj, i) {
j++;
return obj[key] == value;
})
if (!result) {
return -1;
} else {
return j;
};
}
alert(indexOfObject(myArray,"hello","world"));
答案 24 :(得分:0)
此处的大多数回答都无法解决所有情况。 我发现这个解决方案更好:
const isInarray = myArr.filter((obj) => obj.hello === 'stevie' && obj.foo === 'baz').length > 0;
if (!isInArray) {
....
}
答案 25 :(得分:-1)
这没有自定义代码
var arr, a, found;
arr = [{x: 1, y: 2}];
a = {x: 1, y: 2};
found = JSON.stringify(arr).indexOf(JSON.stringify(a)) > - 1;
// found === true
注意:这不会给出实际索引,它只会告诉您的对象是否存在于当前数据结构中
答案 26 :(得分:-1)
您可以创建自己的原型来执行此操作:
类似的东西:
Array.prototype.indexOfObject = function (object) {
for (var i = 0; i < this.length; i++) {
if (JSON.stringify(this[i]) === JSON.stringify(object))
return i;
}
}
答案 27 :(得分:-2)
我更愿意使用findIndex()
方法:
var index = myArray.findIndex('hello','stevie');
index
会为您提供索引编号。