What\'s the best method to get the index of an array which contains objects?
Imagine this scenario:
var hello = {
hello: \'world\',
foo: \'ba
You can create your own prototype to do this:
something like:
Array.prototype.indexOfObject = function (object) {
for (var i = 0; i < this.length; i++) {
if (JSON.stringify(this[i]) === JSON.stringify(object))
return i;
}
}
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.
Here is the test's page: https://jsbench.me/9hjewv6a98
I will prefer to use findIndex()
method:
var index = myArray.findIndex('hello','stevie');
index
will give you the index number.
Array.prototype.findIndex is supported in all browsers other than IE (non-edge). But the polyfill provided is nice.
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 findIndex which stops iterating once a match is found.
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:
For example,
var a = {obj: 0};
var b = [a];
b.indexOf({obj: 0}); // -1 not found
array.filter(function(item, indx, arr){ return(item.hello === 'stevie'); })[0];
Mind the [0]
.
It is proper to use reduce
as in Antonio Laguna
's answer.
Apologies for the brevity...
Using the ES6 findIndex method, without lodash or any other libraries, you can write:
function deepIndexOf(arr, obj) {
return arr.findIndex(function (cur) {
return Object.keys(obj).every(function (key) {
return obj[key] === cur[key];
});
});
}
This will compare the immediate properties of the object, but not recurse into the properties.
If your implementation doesn't provide findIndex
yet (most don't), you can add a light polyfill that supports this search:
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];
});
});
}
(from my answer on this dupe)