A robust way to compare two arrays (or objects) and check if they’re equal to each other.
You could have a simple array, like this one:
var arr = [1, 2, 3, 4, 5];
Or, you could have a complex, multidimensional array with various types of inputs:
var arr = [1, 'something', 3, {
item1: 42,
item2: 'another thing',
item3: function () {
console.log('running!');
}
}, 5];
To properly compare two arrays or objects, we need to check:
- That they’re the same object type (array vs. object).
- That they have the same number of items.
- That each item is equal to its counterpart in the other array or object.
- That they’re the same object type (array vs. object vs. string vs. number vs. function).
- That they have the same value.
And if the item is itself an array or object, we need to compare all of its values against that same items values in the other array or object.
Here’s the helper function:
/*!
* Check if two objects or arrays are equal
* (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {*} obj1 The first item
* @param {*} obj2 The second item
* @return {Boolean} Returns true if they're equal in value
*/
function isEqual (obj1, obj2) {
/**
* More accurately check the type of a JavaScript object
* @param {Object} obj The object
* @return {String} The object type
*/
function getType (obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
function areArraysEqual () {
// Check length
if (obj1.length !== obj2.length) return false;
// Check each item in the array
for (let i = 0; i < obj1.length; i++) {
if (!isEqual(obj1[i], obj2[i])) return false;
}
// If no errors, return true
return true;
}
function areObjectsEqual () {
if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;
// Check each item in the object
for (let key in obj1) {
if (Object.prototype.hasOwnProperty.call(obj1, key)) {
if (!isEqual(obj1[key], obj2[key])) return false;
}
}
// If no errors, return true
return true;
}
function areFunctionsEqual () {
return obj1.toString() === obj2.toString();
}
function arePrimativesEqual () {
return obj1 === obj2;
}
// Get the object type
let type = getType(obj1);
// If the two items are not the same type, return false
if (type !== getType(obj2)) return false;
// Compare based on type
if (type === 'array') return areArraysEqual();
if (type === 'object') return areObjectsEqual();
if (type === 'function') return areFunctionsEqual();
return arePrimativesEqual();
}