Compare two array or object with JavaScript

Learn how to compare array or object with javascript.

There are no specific built-in methods available to us to compare two different arrays or objects in javascript. So we will see how we can create our own custom function which will compare two different objects.

Basic approach to compare array and object in javascript.

The most basic approach is to convert the whole array or the object to a string then compare if those strings are equal or not.

To convert an array or object we will be using JSON.stringify().

let a = [1, 2, 3, 4, 5];
let b = [1, 2, 3, 4, 5];

// "[1, 2, 3, 4, 5]"==="[1, 2, 3, 4, 5]"
console.log(JSON.stringify(a) === JSON.stringify(b));

//true

This may seem to be working fine, but this approach fails when we change the order of the elements.

let a = [1, 2, 3, 4, 5];
let b = [1, 2, 4, 5, 3];

// "[1, 2, 3, 4, 5]"==="[1, 2, 4, 5, 3]"
console.log(JSON.stringify(a) === JSON.stringify(b));

//false

Technically both the arrays are having the same elements and are equal in length but it fails in the comparison. The same happens with the objects.

let a = {a: 1, b: 2, c: 3};
let b = {b: 2, a: 1, c: 3};

//"{'a':1,'b':2,'c':3}" "{'b':2,'a':1,'c':3}"
console.log(JSON.stringify(a) === JSON.stringify(b));

//false

Comparing only arrays (Single and Multi dimensional).

We will create our own custom function which will compare only two different arrays.

In this, we will check

  • If both the inputs are array or not.
  • If the current element is array (muti-dimensional) then recursively check its elements with the corresponding element.
  • Else compare both the elements and return the result.
let compare = (arr1,arr2) => {
   //If not array then return false
   if(!arr1 || !arr2) return false;
    
   if(arr1.length !== arr2.length) return false;
  
   let result;
  
    for(let i = 0; i < arr1.length; i++){
      if(Array.isArray(arr1[i]) && Array.isArray(arr2[i])){
          result = compare(arr1[i], arr2[i]);
        }else if(arr1[i] === arr2[i]){
          result = true;
        }else{
          result = false;
        }
      
      if(!result){
        break;
      }
    }
  
   return result 
}

console.log(compare([1,2,3],[1,2,3]));
// true

console.log(compare([1,2],[1,2,3]));
//false

console.log(compare([[1, 2], [3, 4]],[[1, 2],[3, 4, 6]]));
//false

console.log(compare([[1, 2], [3, 4]],[[1, 2], [3, 4]]));
//true

console.log(compare([1, 2, [3, 4, 5]],[1, 2, [3, 4, 5]]));
//true

console.log(compare([], [1, 2, [3, 4, 5]]));
//false

This method works great if you only have arrays and nested arrays. If it will contain an object or function then it will fail.


Method 3:- Compare array or object with javascript.

This is a much more robust way to check if two different arrays or objects are equal or not.

With this method, we will be comparing more complex arrays. Something like this where an array can have any value possible.

let arr = [1, 'Prashant', 3, {
	a: 42,
	b: 'another thing',
	c: function () {
		console.log('running!');
	}
}, 5];

To perfectly compare an array or object we need to check multiple things.

  • If they are same type (Object or Array).
  • They have the same number of elements.
  • Each element is equal to the other element which we are comparing with.
  • They are of same type (array, object, string, number, function).
  • They have same value.

If the element itself is an array or object then we need to compare all its items with the items of the corresponding array or object.

First, we will create a helper function that will be taking the two different inputs which need to be compared.

let compare = (current, other) => {
   //Comparison will be done here.
}

We will be performing different comparison tests in our function and if any of them fail then we will return false.

Some basic tests

First check if the inputs are either array or object.

We are not comparing anything other than an array or object. So test it to make sure that the inputs we get are either array or object.

let compare = (current, other) => {
  // Get the inputs  type
  let currentType = Object.prototype.toString.call(current);
  
  // Get the other type
  let otherType = Object.prototype.toString.call(other);
  
  // If items are not an object or array, return false
  if (['[object Array]', '[object Object]'].indexOf(currentType) < 0 || ['[object Array]', '[object Object]'].indexOf(otherType) < 0) return false;

  // Other comparisons will happen here

  //If all tests are passed then
  return true
}

Check if both values are of same type.

If one value is of type array and another value is of type object then they are not equal so eliminate them.

let compare = (current, other) => {
  // Get the inputs  type
  let currentType = Object.prototype.toString.call(current);
  
  // Get the other type
  let otherType = Object.prototype.toString.call(other);
  
  // If items are not an object or array, return false
  if (['[object Array]', '[object Object]'].indexOf(currentType) < 0 || ['[object Array]', '[object Object]'].indexOf(otherType) < 0) return false;

  // If the two inputs are not the same type, return false
  if (currentType !== otherType) return false;

  // Other comparisons will happen here

  //If all tests are passed then
  return true
}

Check if both values are of equal size.

Compare the length of the both the inputs.

let compare = (current, other) => {
  // Get the inputs  type
  let currentType = Object.prototype.toString.call(current);
  
  // Get the other type
  let otherType = Object.prototype.toString.call(other);
  
  // If items are not an object or array, return false
  if (['[object Array]', '[object Object]'].indexOf(currentType) < 0 || ['[object Array]', '[object Object]'].indexOf(otherType) < 0) return false;

  // If the two inputs are not the same type, return false
  if (currentType !== otherType) return false;

  // Compare the length of the length of the two items
  let currentLen = currentType === '[object Array]' ? current.length : Object.keys(current).length;
  let otherLen = otherType === '[object Array]' ? other.length : Object.keys(other).length;
  if (currentLen !== otherLen) return false;

  // Other comparisons will happen here

  //If all tests are passed then
  return true
}

Check if elements of both input match.

Check if the elements inside both the elements are same or not.

let compare = (current, other) => {
  // Get the inputs  type
  let currentType = Object.prototype.toString.call(current);
  
  // Get the other type
  let otherType = Object.prototype.toString.call(other);
  
  // If items are not an object or array, return false
  if (['[object Array]', '[object Object]'].indexOf(currentType) < 0 || ['[object Array]', '[object Object]'].indexOf(otherType) < 0) return false;

  // If the two inputs are not the same type, return false
  if (currentType !== otherType) return false;

  // Compare the length of the length of the two items
  let currentLen = currentType === '[object Array]' ? current.length : Object.keys(current).length;
  let otherLen = otherType === '[object Array]' ? other.length : Object.keys(other).length;
  if (currentLen !== otherLen) return false;
  
  // Compare properties
   if (currentType === '[object Array]') {
	for (var i = 0; i < currentLen; i++) {
	    // Compare the item
	}
   } else {
	for (var key in current) {
	    if (current.hasOwnProperty(key)) {
		// Compare the item
	    }
	}
   }

  // Other comparisons will happen here

  //If all tests are passed then
  return true
}

For comparing values of both the inputs we will be creating a helper function. That can be used for both the comparison and will check other possible test cases.


Comparison function to check values of array or object

Again check the type of the element first.

let equal = (item1, item2) => {
  // Get the object type
  let itemType = Object.prototype.toString.call(item1);

  // If an object or array, compare recursively
  if (['[object Array]', '[object Object]'].indexOf(itemType) >= 0) {
      if (!compare(item1, item2)) return false;
  }
}

A simple comparison

Check if both inputs are of same type or not.

let equal = (item1, item2) => {
  // Get the object type
  let itemType = Object.prototype.toString.call(item1);

  // If an object or array, compare recursively
  if (['[object Array]', '[object Object]'].indexOf(itemType) >= 0) {
      if (!compare(item1, item2)) return false;
  }else{
     // If the two items are not the same type, return false
     if (itemType !== Object.prototype.toString.call(item2)) return false;
  }
}

Check if elements are equal.

We can simply perform the strict equality check === to check if both the elements are equal or not. However if the element is a function then we will need to convert it to a string and then compare it.

We will use toString() method to convert the function to a string.

let equal = (item1, item2) => {
  // Get the object type
  let itemType = Object.prototype.toString.call(item1);

  // If an object or array, compare recursively
  if (['[object Array]', '[object Object]'].indexOf(itemType) >= 0) {
      if (!compare(item1, item2)) return false;
  }else{
     // If the two items are not the same type, return false
     if (itemType !== Object.prototype.toString.call(item2)) return false;

     // If it's a function, convert to a string and compare
     // Otherwise, just compare
     if (itemType === '[object Function]') {
	if (item1.toString() !== item2.toString()) return false;
     } else {
 	if (item1 !== item2) return false;
     }
  }
};

We can use this equality checker function in our compare function and get the result.


Complete function to compare two arrays or objects.

let compare = (current, other) => {
  // Get the inputs  type
  let currentType = Object.prototype.toString.call(current);
  
  // Get the other type
  let otherType = Object.prototype.toString.call(other);
  
  // If items are not an object or array, return false
  if (['[object Array]', '[object Object]'].indexOf(currentType) < 0 || ['[object Array]', '[object Object]'].indexOf(otherType) < 0) return false;

  // If the two inputs are not the same type, return false
  if (currentType !== otherType) return false;

  // Compare the length of the length of the two items
  let currentLen = currentType === '[object Array]' ? current.length : Object.keys(current).length;
  let otherLen = otherType === '[object Array]' ? other.length : Object.keys(other).length;
  if (currentLen !== otherLen) return false;
  
  //Helper function to check the equality
  let equal = (item1, item2) => {
      // Get the object type
      let itemType = Object.prototype.toString.call(item1);

      // If an object or array, compare recursively
      if (['[object Array]', '[object Object]'].indexOf(itemType) >= 0) {
          if (!compare(item1, item2)) return false;
      }else{
          // If the two items are not the same type, return false
          if (itemType !== Object.prototype.toString.call(item2)) return false;

          // If it's a function, convert to a string and compare
          // Otherwise, just compare
          if (itemType === '[object Function]') {
        	if (item1.toString() !== item2.toString()) return false;
          } else {
        	if (item1 !== item2) return false;
          }
      }
   };

  // Compare properties
   if (currentType === '[object Array]') {
	for (var i = 0; i < currentLen; i++) {
	    // Compare the item
            if (equal(current[i], other[i]) === false) return false;
	}
   } else {
	for (var key in current) {
	    if (current.hasOwnProperty(key)) {
		// Compare the item
                if (equal(current[key], other[key]) === false) return false;
	    }
	}
   }

  //If all tests are passed then
  return true
}
let arr1 = [1, 2, 3, 4, 5];
let arr2 = [1, 3, 2, 4, 5];
console.log(compare(arr1, arr2)); 
// returns false

let arrObj1 = [1, 2, {
	a: 1,
	b: 2,
	c: 3,
  d: function(){
    console.log("abcd");
  }
}, 4, 5];
let arrObj2 = [1, 2, {
	c: 3,
	b: 2,
	a: 1,
  d: function(){
    console.log("abcd");
  }
}, 4, 5];
console.log(compare(arrObj1, arrObj2)); 
// returns true

let arr4 = [[1, 2], [3, 4, 5]];
let arr3 = [[1, 2], [3, 4, 5]];
console.log(compare(arr4, arr3)); 
// returns true

If you want you can use other libraries as well like _.isEqual(obj1, obj2) of lodash.