0

I have an array of two nested arrays.

var array = [ [a,b,c], [a,b,c] ]

Despite the array elements being identical, the following code returns true:

if (array[0] !== array[1]) {
  console.log(array[0])
  console.log(array[1])
}

// [a,b,c]
// [a,b,c]

And the following code returns false:

if (array[0] === array[1]) {
  console.log(array[0])
  console.log(array[1])
}

It seems to be comparing the indices instead of the elements.

What is going on here?

Sometimes I will be comparing 3 or possibly even 4 nested arrays to each other. For instance, if ( array[0] === array[1] || array[0] === array[2] || array[1] === array[2] ) // do this. Notably, a and c will always be references to actual HTML elements, whereas b will be a number. Is there not a simple way to accomplish this nowadays?

oldboy
  • 5,729
  • 6
  • 38
  • 86

1 Answers1

1

You are comparing object references, not object values. The pointers to memory are different, and as a result the comparison is false.

Here is a simple example using html elements in the arrays.

var a1 = document.querySelectorAll('div');
var a2 = document.querySelectorAll('div');
var a3 = document.querySelectorAll('div');
var array = [Array.from(a1),Array.from(a2),Array.from(a3)];

console.log(array[0].every((v,i) => array.slice(1).every(ai => v == ai[i])));
<div>1</div><div>2</div><div>3</div>
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • Where can I find more info about this? Or how would I go about comparing object values instead of references? By caching `array[0]` and `array[1]` as variables, and then comparing those variables, would I then be comparing object values? – oldboy Jun 16 '17 at 20:31
  • The linked duplicate by Ori Drori explains the process of comparing the values very well, I would suggest looking there. – Travis J Jun 16 '17 at 20:43
  • Thanks. I already have begun to do so. It seems unnecessarily complicated. Sometimes in my code I've needed to compare 3 nested arrays like so: `if ( a[0] === a[1] || a[0] === a[2] || a[1] === a[2] ) // do this` there's not a simple way to achieve this in 2017? – oldboy Jun 16 '17 at 20:50
  • `if( a.every(ai => b.every(bi => bi == ai)) )` will do it if you are just looking at numbers. The reason those others are so in depth is because when you start looking at other values, or using testing, or if there are objects in there, it starts to get a little more complicated. – Travis J Jun 16 '17 at 20:54
  • yeah, `a` and `c` will always be references to actual html elements. i'm at a loss :/ – oldboy Jun 16 '17 at 20:57
  • Oh, right they are nested. You would need to use `if( array[0].every((v,i) => v == array[1][i]) )`. The html elements are stored as objects, however, if you compare two of the same elements, they will have the same object reference, and as a result return true for the comparison. See edit for an example. – Travis J Jun 16 '17 at 21:09
  • Awesome!! I've tested it in a jsfiddle with a strict comparison and it works. Will strict comparison work in all cases? I'll mark this as an answer – oldboy Jun 16 '17 at 21:12
  • Likewise, is there a way to use this same method to compare 3 arrays (I've edited my question above) without nesting if/else statements? – oldboy Jun 16 '17 at 21:14
  • I am not sure what you mean by in all cases. All strict comparison does is ensure that there is no implicit conversion when making to comparisons. In other words 5 === "5" is false, while 5 == "5" is true. If you were to use `v === array[1][i]` in this example, it would still work. – Travis J Jun 16 '17 at 21:14
  • Comparing 3 arrays would just require using more `every`, namely to iterate the array[1] or array[0] or array[2] – Travis J Jun 16 '17 at 21:15
  • yeah, like so: `if ( array[0].every((v,i) => v === array[1][i]) || array[0].every((v,i) => v === array[2][i]) || array[1].every((v,i) => v === array[2][i]) )`, right? i just have this nagging feeling that there should be a way to accomplish this without so many damned operations lol – oldboy Jun 16 '17 at 21:16
  • Every layer of complexity brings more lines of code. – Travis J Jun 16 '17 at 21:18
  • life is unfair :.( – oldboy Jun 16 '17 at 21:20
  • `array[0].every((v,i) => array.slice(1).every(ai => v == ai[i]))` will compare the first array to all the rest of the arrays. – Travis J Jun 16 '17 at 21:21
  • 1
    [Life isn't fair](https://meta.stackexchange.com/questions/202652/life-isnt-fair/202912#202912) – Travis J Jun 16 '17 at 21:22