Javascript 对象数组中的indexOf方法?
获取包含对象的数组索引的最佳方法是什么 想象一下这个场景:Javascript 对象数组中的indexOf方法?,javascript,Javascript,获取包含对象的数组索引的最佳方法是什么 想象一下这个场景: var hello = { hello: 'world', foo: 'bar' }; var qaz = { hello: 'stevie', foo: 'baz' } var myArray = []; myArray.push(hello,qaz); 现在我想得到对象的索引,hello属性是'stevie',在这个例子中,它是1 我是JavaScript的新手,我不知道是否有一个简单的方法,或者
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello,qaz);
现在我想得到对象的索引,hello属性是'stevie',在这个例子中,它是1
我是JavaScript的新手,我不知道是否有一个简单的方法,或者我是否应该构建自己的函数来实现这一点。在除IE non edge之外的所有浏览器中都受支持。但是提供的服务很好
var idx = myArray.reduce( function( cur, val, index ){
if( val.hello === "stevie" && cur === -1 ) {
return index;
}
return cur;
}, -1 );
var indexOfStevie = myArray.findIndex(i => i.hello === "stevie");
使用map的解决方案是可以的。但每次搜索时,您都会对整个数组进行迭代。这只是findIndex最糟糕的情况,一旦找到匹配项,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
pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');
我喜欢Pablo的答案,但是ArrayindexOf和Arraymap并不是在所有浏览器上都能工作。下划线将使用本机代码(如果可用),但也有回退。此外,它还提供了Pulk方法,可以完全实现Pablo的匿名映射方法的功能
var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();
我更喜欢使用findIndex方法:
index将为您提供索引编号。您可以创建自己的原型来执行此操作: 比如:
Array.prototype.indexOfObject = function (object) {
for (var i = 0; i < this.length; i++) {
if (JSON.stringify(this[i]) === JSON.stringify(object))
return i;
}
}
注意[0]
在安东尼奥·拉古纳的回答中使用reduce是恰当的
抱歉这么简单…我制作了一个通用函数来检查下面的代码是否适用于任何对象
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表示未找到匹配项,第二个警报将返回0表示找到匹配项。Brief
用例:
应用程序编程接口:
这是在数组中查找对象索引的方法
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;
}
}
使用u.findIndex from
下面是一个例子
_.findIndex[{a:1},{a:2,c:10},{a:3}],{a:2,c:10}//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
注意:这并没有给出实际的索引,它只告诉您的对象是否存在于当前的数据结构中
使用ES6,不使用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];
});
});
}
根据我在上的回答,您可以使用适用于不受支持的浏览器的
我看到人们否决了这个答案,我希望他们这样做是因为语法错误,因为在我看来,这是最优雅的方式
如果数组中的元素满足提供的测试函数,findIndex方法将返回数组中的索引。否则返回-1
例如:
var hello={
您好:'世界',
福:“酒吧”
};
变量qaz={
你好:'史蒂夫',
福:“巴兹”
}
var myArray=[];
myArray.pushhello,qaz;
var index=myArray.findIndexfunctionelement{
return element.hello=='stevie';
};
警报指数 试试这个:
console.log(Object.keys({foo:"_0_", bar:"_1_"}).indexOf("bar"));
简单:
myArray.indexOf(myArray.filter(function(item) {
return item.hello == "stevie"
})[0])
您可以使用本机且方便的函数Array.prototype.findIndex,基本上: 如果数组中的元素满足提供的测试函数,findIndex方法将返回数组中的索引。否则返回-1 请注意,Internet Explorer、Opera和Safari不支持此功能,但您可以使用下面链接中提供的Polyfill 更多信息: var hello={ 您好:'世界', 福:“酒吧” }; 变量qaz={ 你好:'史蒂夫', 福:“巴兹” } var myArray=[]; myArray.pushhello,qaz; var index=myArray.findIndexfunctionelement,索引,数组{ if element.hello==='stevie'{ 返回true; } }; 警报“stevie在索引处:”+索引 你可以简单地使用 常数someId=2; 常量数组=[{id:1},{id:2},{id:3}]; const index=array.reducei,item,index=>item.id==someId?指数:i,-1;
警报“someId”+someId+”位于索引“+index”处 在ES2015中,这非常简单:
myArray.map(x => x.hello).indexOf('stevie')
或者,对于较大的阵列,可能具有更好的性能:
myArray.findIndex(x => x.hello === 'stevie')
如果你只对找到这个职位感兴趣,请参阅 pos=myArray.mapfunctione{returne e.hello;}.indexOf'stevie' 但是,如果您希望找到元素,也就是说,如果您想做类似于myArray[pos]的事情,那么有一种更有效的单行方法,使用filter element=myArray.filtere=>e.hello===='stevie'[0] 参见性能结果~+42%运行/秒:
我在这里对各种答案进行了性能测试,任何人都可以自己运行: 根据我在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");
如果您的对象与您在数组中使用的对象是同一个对象,那么您应该能够像获取字符串一样获取对象的索引
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
我比较了几种方法,得到了解决这个问题最快的方法。这是给我的 哎呀。它比任何其他方法快5倍以上
这是测试页面:然而,这里的大多数其他答案都是有效的。有时候,最好在您将要使用的位置附近制作一个简短的函数
// 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');
这取决于什么对你重要。它可以节省代码行数,并且非常聪明地使用一行代码,或者将一个通用的解决方案放在涵盖各种边缘情况的地方。但有时最好只是说:在这里,我是这样做的,而不是让未来的开发人员从事额外的逆向工程工作。特别是如果你认为自己是一个新手。p> 这里的大多数回答并不能解决所有问题。 我发现这个解决方案更好: const isInarray=myArr.filterobj=>obj.hello==='stevie'和&obj.foo==='baz'。长度>0; 如果伊西纳雷{ .... }
你想合并hello和qaz这两个对象吗?不想。我想要一个数组中的对象列表。啊,好的!您想知道整个对象在数组中的位置,它有一个已定义的属性。我找到了一个非常简单的函数来解决这个问题,答案如下:var elementPos=array.mapfunctionx{return x.id;}.indexofidyouraeloking;var objectFound=array[elementPos];[link]如果ES6适合您,ES6 Array.indexOf优于公认的答案-请参阅下面的完整示例该函数的searchterm比较错误,因为它应该是searchterm:存在多个occurences@SteveBennett这是一个性能优化的版本;当for循环的变量初始化时,数组的长度只需确定一次。在您的情况下,每次迭代都会重新检查长度。但是,如果性能不是很高,这并不重要。答案很好,但我做了一些性能基准测试,发现这里提到的基于函数的答案似乎是第二高性能的答案。唯一更有效的方法是将其放入原型中,而不是如中所述的函数中。这应该是公认的答案。现在大多数浏览器都支持Array.prototype.mapIt,IE8不支持它,但如果这不是问题的话,这是最好的解决方案。嗯。。。Array.prototype.map创建了一个包含映射项的全新数组,这难道不值得注意吗?那么,如果你有一个包含1000个元素的数组,你首先创建了另一个包含1000个元素的数组,然后搜索它?我认为值得一看这种方法与简单for循环的性能。特别是当你在资源有限的移动平台上运行时。@Doug虽然你关于性能的观点确实正确,在他们分析瓶颈之前,对于一个几乎被定义为IO/网络绑定的应用程序,谁会用七行代码替换一行代码呢;非常方便!虽然我会选择prototype.indexOfObject,以免干扰现有的Array.indexOf方法。Array.prototype.indexOfObject=functionproperty,值{for var i=0,len=this.length;i
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];
});
});
}
console.log(Object.keys({foo:"_0_", bar:"_1_"}).indexOf("bar"));
myArray.indexOf(myArray.filter(function(item) {
return item.hello == "stevie"
})[0])
myArray.map(x => x.hello).indexOf('stevie')
myArray.findIndex(x => x.hello === '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;
}
myArray.indexOfObject("hello", "stevie");
myArray.indexOfObject("hello", "stevie");
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"));
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
// 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');