indexOf method in an object array?

indexOf method in an object array?

What’s the best method to get the index of an array which contains objects?
Imagine this scenario:
var hello = {
hello: ‘world’,
foo: ‘bar’
};
var qaz = {
hello: ‘stevie’,
foo: ‘baz’
}

var myArray = [];
myArray.push(hello,qaz);

Now I would like to have the indexOf the object which hello property is ‘stevie’ which, in this example, would be 1.
I’m pretty newbie with JavaScript and I don’t know if there is a simple method or if I should build my own function to do that.

Solutions/Answers:

Solution 1:

I think you can solve it in one line using the map function:

pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');

Solution 2:

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.


There’s not really a concise way (when devs had to worry about IE8), but here’s a common solution:

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:

  1. Don’t use for…in loops on arrays
  2. Be sure to break out of the loop or return out of the function once you’ve found your “needle”
  3. Be careful with object equality

For example,

var a = {obj: 0};
var b = [a];
b.indexOf({obj: 0}); // -1 not found

Solution 3:

In ES2015, this is pretty easy:

myArray.map(x => x.hello).indexOf('stevie')

or, probably with better performance for larger arrays:

myArray.findIndex(x => x.hello === 'stevie')

Solution 4:

var idx = myArray.reduce( function( cur, val, index ){

    if( val.hello === "stevie" && cur === -1 ) {
        return index;
    }
    return cur;

}, -1 );

Solution 5:

I like Pablo’s answer, but Array#indexOf and Array#map don’t work on all browsers. Underscore will use native code if it’s available, but has fallbacks as well. Plus it has the pluck method for doing exactly what Pablo’s anonymous map method does.

var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();

Solution 6:

Or prototype it :

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");