0

Here is a simple example of an array that contains at least one other array. I want a way to find the index of an array, within an array. However, the code I have below does not work:

var arr = [1,2,[1,2]];
console.log(arr.indexOf([1,2])); //-> -1

for (var i = 0; i < arr.length; i++) {
  if (arr[i] == [1,2])
    return 'true' // does not return true
}

Intuitively, this should work but does not:

if ([1,2] == [1,2]) return 'true' // does not return true

Can someone explain why it does not work, and offer an alternative solution? Thanks!

dmwong2268
  • 3,315
  • 3
  • 19
  • 20
  • what result do you expect? – Nina Scholz Oct 05 '15 at 17:11
  • 4
    in JS arrays are compared by **reference**. that's why `[1,2] != [1,2]` – hindmost Oct 05 '15 at 17:13
  • 3
    The first `[1,2]` is not the same as the second `[1,2]`: they are different objects. – apsillers Oct 05 '15 at 17:13
  • 2
    Possible duplicate of [How to check if two arrays are equal with JavaScript?](http://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript) – Shelvacu Oct 05 '15 at 17:15
  • possible duplicate of [How to compare arrays in JavaScript?](http://stackoverflow.com/q/7837456/710446) – apsillers Oct 05 '15 at 17:17
  • In this case you can simply cast them to strings since the values are simply numbers: `arr[i].toString() === [1,2].toString()` – Spencer Wieczorek Oct 05 '15 at 17:17
  • @SpencerWieczorek, this method will take too many resources for large arrays (it's just inefficient). – Dmitriy Simushev Oct 05 '15 at 17:18
  • You could just store `[1,2]` in a variable first, assign into the array and then use `indexOf`. Although what this is actually saying is: *look for this array inside this other array* and not *look for an array that looks like this array inside this other array* – MinusFour Oct 05 '15 at 17:21
  • @DmitriySimushev As I've clearly stated I said *"In this case you can "*, the point being this is fine to use on small arrays with simple values. Despite in large cases iteration needs to be done completely on the arrays anyways, it's not going to be efficient regardless. – Spencer Wieczorek Oct 05 '15 at 17:32

3 Answers3

1

No, but you can check it yourself:

var a = [1,2], b = [1,2];

a.length === b.length && a.every(function(x,y) { return x === b[y]; });
Malk
  • 11,855
  • 4
  • 33
  • 32
0

Arrays in JavaScript are compared by reference not by value. That is why

console.log([1,2] == [1,2])

returns false.

You need a custom function that could compare arrays. If you want to check only the first level of nesting you can use this code:

var compareArrays = function(a, b) {
    if (a.length !== b.length) {
        return false;
    }

    for (var i = 0, len = a.length; i < len; i++) {
        if (a[i] !== b[i]) {
            return false;
        }
    }

    return true;
}
Dmitriy Simushev
  • 308
  • 1
  • 16
0

You are confusing the definitions of similar objects vs. the same object. Array.prototype.indexOf() compares the objects using the strict equality comparison algorithm. For (many) objects, this means an object reference comparison (i.e. the object's unique identifier, almost like its memory address).

In your example above, you are trying to treat two similar arrays as though they were the same array, and that's why it doesn't work. To do what you are trying to do, you need to use the same array. Like this:

var testArr = [1,2]; //a specific object with a specific reference
var arr = [1,2,testArr]; //the same array, not a different but similar array
console.log(arr.indexOf(testArr)); //returns 2

If you just want to know where arrays occur in the parent array, use Array.isArray():

...
if(Array.isArray(arr[i])) {
    //do something
}
...

Hopefully that helps!

Ian
  • 3,806
  • 2
  • 20
  • 23