Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Array.indexOf doesn't find identical looking objects

I have array with objects.

Something Like this:

var arr = new Array(   {x:1, y:2},   {x:3, y:4} ); 

When I try:

arr.indexOf({x:1, y:2}); 

It returns -1.

If I have strings or numbers or other type of elements but object, then indexOf() works fine.

Does anyone know why and what should I do to search object elements in array?

Of course, I mean the ways except making string hash keys for objects and give it to array...

like image 781
Jibla Avatar asked Sep 26 '12 14:09

Jibla


People also ask

Does array indexOf work with objects?

To find the index of an object in an array, by a specific property: Use the map() method to iterate over the array, returning only the value of the relevant property. Call the indexOf() method on the returned from map array. The indexOf method returns the index of the first occurrence of a value in an array.

What does array indexOf () return if the item being searched is not found?

The indexOf() method returns -1 if the value is not found.

Does indexOf work on 2d arrays?

You cannot use indexOf to do complicated arrays (unless you serialize it making everything each coordinate into strings), you will need to use a for loop (or while) to search for that coordinate in that array assuming you know the format of the array (in this case it is 2d).

Is there an indexOf for arrays?

IndexOf(Array, Object, Int32) Searches for the specified object in a range of elements of a one-dimensional array, and returns the index of its first occurrence. The range extends from a specified index to the end of the array.


2 Answers

indexOf compares searchElement to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator).

You cannot use === to check the equability of an object.

As @RobG pointed out

Note that by definition, two objects are never equal, even if they have exactly the same property names and values. objectA === objectB if and only if objectA and objectB reference the same object.

You can simply write a custom indexOf function to check the object.

function myIndexOf(o) {         for (var i = 0; i < arr.length; i++) {         if (arr[i].x == o.x && arr[i].y == o.y) {             return i;         }     }     return -1; } 

DEMO: http://jsfiddle.net/zQtML/

like image 74
Selvakumar Arumugam Avatar answered Oct 13 '22 23:10

Selvakumar Arumugam


As nobody has mentioned built-in function Array.prototype.findIndex(), I'd like to mention that it does exactly what author needs.

The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.

var array1 = [5, 12, 8, 130, 44];  function findFirstLargeNumber(element) {   return element > 13; }  console.log(array1.findIndex(findFirstLargeNumber)); // expected output: 3 

In your case it would be:

arr.findIndex(function(element) {  return element.x == 1 && element.y == 2; }); 

Or using ES6

arr.findIndex( element => element.x == 1 && element.y == 2 ); 

More information with the example above: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

like image 37
Matt Avatar answered Oct 13 '22 23:10

Matt