Ant*_*una 471 javascript
获取包含对象的数组的索引的最佳方法是什么?
想象一下这种情况:
var hello = {
hello: 'world',
foo: 'bar'
};
var qaz = {
hello: 'stevie',
foo: 'baz'
}
var myArray = [];
myArray.push(hello,qaz);
Run Code Online (Sandbox Code Playgroud)
现在我想拥有属性indexOf的对象,在这个例子中,它将是.hello'stevie'1
我是JavaScript的新手,我不知道是否有一个简单的方法,或者我是否应该构建自己的函数来做到这一点.
Pab*_*lgo 967
我想你可以使用map函数在一行中解决它:
pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');
Run Code Online (Sandbox Code Playgroud)
Joe*_*Joe 345
除IE之外的所有浏览器都支持Array.prototype.findIndex(非边缘).但是提供的polyfill很不错.
var indexOfStevie = myArray.findIndex(i => i.hello === "stevie");
Run Code Online (Sandbox Code Playgroud)
有地图的解决方案没问题.但是你每次搜索都在迭代整个数组.这只是findIndex的最坏情况,它会在找到匹配后停止迭代.
var searchTerm = "stevie",
index = -1;
for(var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i].hello === searchTerm) {
index = i;
break;
}
}
Run Code Online (Sandbox Code Playgroud)
或作为一种功能:
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
Run Code Online (Sandbox Code Playgroud)
只是一些说明:
例如,
var a = {obj: 0};
var b = [a];
b.indexOf({obj: 0}); // -1 not found
Run Code Online (Sandbox Code Playgroud)
Ste*_*ett 115
在ES2015中,这非常简单:
myArray.map(x => x.hello).indexOf('stevie')
Run Code Online (Sandbox Code Playgroud)
或者,对于较大的阵列可能具有更好的性能:
myArray.findIndex(x => x.hello === 'stevie')
Run Code Online (Sandbox Code Playgroud)
Esa*_*ija 24
var idx = myArray.reduce( function( cur, val, index ){
if( val.hello === "stevie" && cur === -1 ) {
return index;
}
return cur;
}, -1 );
Run Code Online (Sandbox Code Playgroud)
tan*_*ols 17
我喜欢Pablo的答案,但是Array#indexOf和Array #map不适用于所有浏览器.如果可用,Underscore将使用本机代码,但也会有后备.此外,它还具有完全符合Pablo匿名地图方法的方法.
var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();
Run Code Online (Sandbox Code Playgroud)
Nat*_*tta 14
或原型:
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");
Run Code Online (Sandbox Code Playgroud)
myArray.indexOf('stevie','hello')
Run Code Online (Sandbox Code Playgroud)
/*****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
Run Code Online (Sandbox Code Playgroud)
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);
}
};
Run Code Online (Sandbox Code Playgroud)
小智 8
您可以使用findIndex()方法:
cosnt myIndex=myArray.findIndex(el=>el.hello==='stevie')
Run Code Online (Sandbox Code Playgroud)
如果 myIndex < 0 则表示不存在
小智 7
如果您的对象与您在数组中使用的对象是同一个对象,您应该能够像获取字符串一样获取对象的索引。
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
Run Code Online (Sandbox Code Playgroud)
我在这里对各种答案进行了一些性能测试,任何人都可以自己运行它们:
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");
Run Code Online (Sandbox Code Playgroud)
这段代码是Nathan Zaetta答案的略微修改版本.
在性能基准测试中,我尝试了目标位于1000个对象数组的中间(索引500)和最终(索引999),即使我将目标放在数组中的最后一项(意思是它必须循环遍历数组中的每一个项目才能找到它仍然最快.
该解决方案还具有作为重复执行最简洁之一的优点,因为只需要重复最后一行:
myArray.indexOfObject("hello", "stevie");
Run Code Online (Sandbox Code Playgroud)
虽然,这里的大多数其他答案都是有效的。有时,最好只是在使用位置附近做一个简短的简单函数。
// 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');
Run Code Online (Sandbox Code Playgroud)
这取决于对您而言重要的内容。它可能节省代码行,并且非常聪明,因此可以使用单行代码,或者将通用解决方案放在涵盖各种边缘情况的地方。但是有时候,最好只是说:“在这里我是这样做的”,而不是让将来的开发人员去做额外的逆向工程。特别是如果您认为自己是“新手”,例如您的问题。
| 归档时间: |
|
| 查看次数: |
506912 次 |
| 最近记录: |