'array indexOf with objects?

I know we can match array values with indexOf in JavaScript. If it matches it wont return -1.

var test = [
    1, 2, 3
]

// Returns 2
test.indexOf(3);

Is there a way to match objects? For example?

var test = [
    {
        name: 'Josh'
    }
]

// Would ideally return 0, but of course it's -1.
test.indexOf({ name: 'Josh' });


Solution 1:[1]

Since the two objects are distinct (though perhaps equivalent), you can't use indexOf.

You can use findIndex with a callback, and handle the matching based on the properties you want. For instance, to match on all enumerable props:

var target = {name: 'Josh'};
var targetKeys = Object.keys(target);
var index = test.findIndex(function(entry) {
    var keys = Object.keys(entry);
    return keys.length == targetKeys.length && keys.every(function(key) {
        return target.hasOwnProperty(key) && entry[key] === target[key];
    });
});

Example:

var test = [
    {
        name: 'Josh'
    }
];

var target = {name: 'Josh'};
var targetKeys = Object.keys(target);
var index = test.findIndex(function(entry) {
    var keys = Object.keys(entry);
    return keys.length == targetKeys.length && keys.every(function(key) {
        return target.hasOwnProperty(key) && entry[key] === target[key];
    });
});
console.log(index);

Note that findIndex was added in ES2015, but is fully polyfillable.

Solution 2:[2]

Nope, you can't and the explanation is simple. Despite you use the same object literal, two different objects are created. So test would have another reference for the mentioned object if you compare it with the reference you are looking for in indexOf.

Solution 3:[3]

This is kind of custom indexOf function. The code just iterates through the items in the object's array and finds the name property of each and then tests for the name you're looking for. Testing for 'Josh' returns 0 and testing for 'Kate' returns 1. Testing for 'Jim' returns -1.

var test = [
  {
    name: 'Josh'
  },
  {
    name: 'Kate'
  }
]

myIndexOf('Kate')

function myIndexOf(name) {
  testName = name;
  for (var i = 0; i < test.length; i++) {
    if(test[i].hasOwnProperty('name')) {
      if(test[i].name === testName) {
        console.log('name: ' + test[i].name + ' index: ' + i);
        return i;
      }
    }
  }
  return -1;
}

Solution 4:[4]

You can loop on array and then look for what you want

 var test = [{ name: 'Josh' }]

const Myname = test.map((item) => { return item.name; }).indexOf("Josh")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 T.J. Crowder
Solution 2 Christos
Solution 3
Solution 4 mohamedhamdy