DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Cover image for 2 arrays of Same value are not equal in JS.
Mysterio
Mysterio

Posted on

2 arrays of Same value are not equal in JS.

Hello Guys today i am going to discuss a very little thing that you might have not noticed in Javascript.
I will show you that thing using an example.

Example 1 -

let array1= [1,5,9,14,17];
let array2= [1,5,9,14,17];

console.log(array1 == array2);
console.log(array1 === array2);
Enter fullscreen mode Exit fullscreen mode

Can you guess what will be the output?

Output -

false
false
Enter fullscreen mode Exit fullscreen mode
  • It returned false in both comparsion although the values are equals, number of elements are also equal so, why it returned false? because everything in javascript is an object and arrays are also objects therefore instead of comparing the values or number of elements , it checks the reference of those array which is different that's why it returned false in both the cases.

Example 2 -

let array1= [1,5,9,14,17];
let array2= [1,5,9,14,17];
let array3 = array1
console.log(array3 === array1);
console.log(array3 === array2);
Enter fullscreen mode Exit fullscreen mode

Can you guess now what will be the output?

Output -

true
false
Enter fullscreen mode Exit fullscreen mode
  • Well the reason it returned true while comparing array3 with array1 is because we stored the reference of array1 in array3 so, both are pointing to the same reference while array3 and array2 comparison returned false because they have different references.

How you can then compare these arrays?

The answer is simple , use the toString method to convert the array into strings and then compare them

Example 3-

let array1= [1,5,9,14,17];
let array2= [1,5,9,14,17];
console.log(array1.toString() === array2.toString());
Enter fullscreen mode Exit fullscreen mode

Output -

true
Enter fullscreen mode Exit fullscreen mode
  • So, now it is comparing string values which is equal that's why it returned true this time.

It looks quite confusing and i tried my best to explain and if you find any point wrong please correct it in the comment section.

THANK YOU FOR CHECKING THIS POST
^^You can help me by some donation at the link below Thank you๐Ÿ‘‡๐Ÿ‘‡ ^^
โ˜• --> https://www.buymeacoffee.com/waaduheck <--

Also check these posts as well
https://dev.to/shubhamtiwari909/javascript-map-with-filter-2jgo

https://dev.to/shubhamtiwari909/e-quotes-3bng

https://dev.to/shubhamtiwari909/deploy-react-app-on-netlify-kl

Top comments (13)

Collapse
 
joelbonetr profile image
JoelBonetR • Edited on

It depends on what do you consider equal.

const arr1 = [1, 2, 3]
const arr2 = [3, 2, 1]
Enter fullscreen mode Exit fullscreen mode

Both have the same length and values, are they "equal"?

/**
 * Checks whether two arrays are equal (same length, same values, same value order)
 * @param {Array<any>} arr1 
 * @param {Array<any>} arr2 
 * @returns {boolean}
 */
const isStrictEqual = (arr1, arr2) => arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);

isStrictEqual([1, 2, 3], [1, 2, 3]) // true
isStrictEqual([1, 2, 3], [3, 2, 1]) // false
Enter fullscreen mode Exit fullscreen mode

There are a bunch of workarounds to cover all meanings depending on what do you consider equal.

/**
 * Checks whether two arrays are equal (same length, same values)
 * @param {Array<any>} arr1 
 * @param {Array<any>} arr2 
 * @returns {boolean}
 */
const isEqual = (arr1, arr2) => {
  const arr2Sorted = arr2.slice().sort();
  return arr1.length === arr2.length && arr1.slice().sort().every( (value, index) =>
      arr2Sorted[index]);
}

isEqual([1, 2, 3], [1, 2, 3]) // true
isEqual([1, 2, 3], [3, 2, 1]) // true
Enter fullscreen mode Exit fullscreen mode

Tricky topic! ๐Ÿ˜‚

Collapse
 
shubhamtiwari909 profile image
Mysterio Author

All i wanted to show how complicated Javascript language is ๐Ÿ˜‚๐Ÿ˜‚

Collapse
 
joelbonetr profile image
JoelBonetR

That will do I guess ๐Ÿ˜‚

Thread Thread
 
shubhamtiwari909 profile image
Mysterio Author

Yeah ๐Ÿ˜‚๐Ÿ˜‚

Collapse
 
smlka profile image
Andrey Smolko

toString() is a not good way (or is good is array's element are primitives). Check that example:

let array1= [1,5,9,14,{a:17}];
let array2= [1,5,9,14,{a:1700}];
console.log(array1.toString() === array2.toString());
// true
Enter fullscreen mode Exit fullscreen mode
Collapse
 
joelbonetr profile image
JoelBonetR • Edited on

Agree. And we can see the reason why doing

const arr1= [1, 5, 9, 14, {a:17}];
const arr2 = [1, 5, 9, 14, {a:1700}];
arr1.toString()  // '1,5,9,14, [object Object]'
arr2.toString()  // '1,5,9,14, [object Object]'
Enter fullscreen mode Exit fullscreen mode

JSON.stringify on the other hand, works better on this:

const arr1= [1, 5, 9, 14, { a: 17 }];
const arr2 = [ 1, 5, 9, 14, { a: 1700 }];
JSON.stringify(arr1) === JSON.stringify(arr2) // false
Enter fullscreen mode Exit fullscreen mode

because

JSON.stringify(arr1) // '[1,5,9,14,{"a":17}]'
JSON.stringify(arr2) // '[1,5,9,14,{"a":1700}]'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
object_required profile image
Nikolai Kim

And with JSON.stringify these two will not be equal:

const arr1 = [ 1, { foo: 2, bar: 3 } ]
const arr2 = [ 1, { bar: 3, foo: 2 } ]
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
joelbonetr profile image
JoelBonetR

Actually they are somewhat different (some props are not in the same order).
That's why this question is so tricky ๐Ÿ˜‚

I let you a couple of snippets that can be useful in certain situations:

/**
 * Retrurns the depth of an Object
 * @param {Object} object 
 * @returns {number}
 */
const depthOf = (obj) => {
  let level = 1;
  for (const key in obj) {
    if (!obj.hasOwnProperty(key)) continue;

    if (typeof obj[key] == 'object') {
      let depth = depthOf(obj[key]) + 1;
      level = Math.max(depth, level);
    }
  }
  return level;
};
Enter fullscreen mode Exit fullscreen mode
/**
 * Transforms Object into Array Recursively
 * @param {Object} obj
 * @returns {Array}
 */
const deepObjectToArray = (obj) => {
  let result = obj;
  if (typeof obj === 'object' && !Array.isArray(obj)) {
    result = Object.entries(obj);
    result.forEach((attr) => {
      attr[1] = deepObjectToArray(attr[1]);
    });
  } else if (Array.isArray(obj)) obj.forEach((v, i, a) => (a[i] = deepObjectToArray(v)));

  return result;
};
Enter fullscreen mode Exit fullscreen mode

Discussing them could deal to an entire post probably ๐Ÿ˜‚

Cheers!

Collapse
 
shubhamtiwari909 profile image
Mysterio Author

Again complicated but beautiful

Collapse
 
shubhamtiwari909 profile image
Mysterio Author

Again you showed us another example of why javascript is complicated

Collapse
 
bwca profile image
Volodymyr Yepishev

Javscrtipt is fabulous:

const a = [1, undefined];
const b = [1];

a[0] === b[0]; // true
a[1] === b[1]; // true
a.toString() === b.toString() //false
Enter fullscreen mode Exit fullscreen mode
Collapse
 
joelbonetr profile image
JoelBonetR

๐Ÿ˜‚ Good one!

Collapse
 
shubhamtiwari909 profile image
Mysterio Author

๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚

๐ŸŒš Browsing with dark mode makes you a better developer.

It's a scientific fact.