1

Is it possible to use array.indexOf passing as searchElement an object. In my example the result is -1.

   var myArray = [{id: 1, name: 'milan'}, {id: 2, name: 'rome'}];
   var idx = myArray.indexOf({id: 1, name: 'milan'});

if not possible what it a faster alternative approach? Maybe using array.filter and return as result value for index?

GibboK
  • 71,848
  • 143
  • 435
  • 658

4 Answers4

2

No, but you could filter for that ...

var myArray = [{id: 1, name: 'milan'}, {id: 2, name: 'rome'}],
    equals = function equals(o1, o2) {
      return o1.id == o2.id && o1.name == o2.name;
    },
    idx = {id: 1, name: 'milan'},
    filtered = myArray.filter(function(object, index,array1) {
      return equals(idx, object);
    });
Florian Salihovic
  • 3,921
  • 2
  • 19
  • 26
  • I understand you point, please have a look it seems there is an error in the code as o.id is not defined, object is used instead – GibboK Oct 24 '13 at 13:24
  • I fixed the code. I passed `object` to address the instance, but `o` in the code ... it should be working now. You could make it a named function and use it where you need it or provide an `equals(o1, o2)` . I'll edit it in a minutes. – Florian Salihovic Oct 25 '13 at 09:29
2

No, you can't use indexOf for that: it uses strict equality for the comparison, and therefore:

console.log({id: 1, name: 'milan'} === {id: 1, name: 'milan'}); // false

Because they're two different object, that contains the same property.

In the close future, you will be able to use the new ES6 Array's method like find and findIndex (they're already implemented in Firefox Nightly for example):

var myArray = [{id: 1, name: 'milan'}, {id: 2, name: 'rome'}];
var idx = myArray.findIndex(({id}) => id === 1); // `idx` will be `0`
var item = myArray.find(({id}) => id === 1); // `item` will contains {id: 1, name: 'milan'}

In the mean time, you have to do that manually; and if you want to compare all the properties is better if you create a deepEqual function or similar.

ZER0
  • 24,846
  • 5
  • 51
  • 54
1

It's not possible because objects are compared with reference equality semantics; two identical objects that are different instances will compare unequal. That means you need to write custom logic for the comparison no matter what.

In the general case you could find the object by iterating over each of its properties and testing if each one exists and also has the same value on a candidate array element (most likely this would need to be recursive). Depending on what the object might contain the comparison method would also need to recognize arrays.

For extremely simple cases such as {id: 1} you could also quick-and-dirty hack it by using JSON.stringify on the input and each element and comparing the results.

Jon
  • 428,835
  • 81
  • 738
  • 806
0

array.filter() method does not return the index it just provide index to filter data but it always returns the whole object of an array who satisfy the condition in .filter()

you can use this logic

function getIndex(myArray, element)
{
    for(var i=0; i<array.length; i++) {
        if(element.id == myArray[i].id)
            return i;
    }
    return -1;
}
Sohil Desai
  • 2,940
  • 5
  • 23
  • 35