2

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' });
Josh
  • 1,455
  • 19
  • 33
  • Please see this; http://stackoverflow.com/questions/11258077/how-to-find-index-of-an-object-by-key-and-value-in-an-javascript-array – Koby Douek Mar 07 '17 at 17:04

4 Answers4

8

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks for your input. I just hope this is effective when my array contains 2000 objects. – Josh Mar 07 '17 at 18:30
  • 2
    @JoshSpears: It'll be *effective*. :-) How *efficient* it'll be will depend on how many "own" properties they have. 2000 is not a lot of objects, even if they have 20-30 "own" properties each I'd be surprised if it took more than a couple of milliseconds. Actually, that's easy to test: https://jsfiddle.net/kxt9a4xr/1/ On my machine, on Chrome, forcing the worst case (the objects all *almost* match, but none actually does), it's 5-7ms. YMMV. – T.J. Crowder Mar 07 '17 at 18:51
0

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.

Christos
  • 53,228
  • 8
  • 76
  • 108
0

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;
}
Chris Sharp
  • 2,005
  • 1
  • 18
  • 32
0

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