HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptTip

Check if two JavaScript objects have the same properties

Submitted by: @import:30-seconds-of-code··
0
Viewed 0 times
javascriptsamechecktwoobjectshavetheproperties

Problem

Given two JavaScript objects, it's not straightforward to compare them for equality. This is because objects are reference types, and two objects with the same properties and values are not considered equal. However, it's not difficult to implement a function that does just that.
First off, let's create a function that compares two objects to determine if the first one contains equivalent property values to the second one. This essentially means checking if the keys of the first object are a superset of the keys of the second object, and if the values of the first object are equal to the values of the second object.
Comparing objects this way requires iterating over the keys of the second object, using Object.keys(), and checking if each key exists in the first object using Array.prototype.every(), Object.prototype.hasOwnProperty().
In order to compare the values of the properties, we can simply use the strict equality operator (===). This will ensure that the values are not only equal but also of the same type.
If, instead, we want to use a custom function to determine value equality, we can simply replace the strict equality operator with the provided function. This function will receive the value of the property in both objects, as well as the key and the objects themselves.

Solution

const matches = (obj, source) =>
  Object.keys(source).every(
    key => obj.hasOwnProperty(key) && obj[key] === source[key]
  );

matches(
  { age: 25, hair: 'long', beard: true },
  { hair: 'long', beard: true }
); // true

matches(
  { hair: 'long', beard: true },
  { age: 25, hair: 'long', beard: true }
); // false


Comparing objects this way requires iterating over the keys of the second object, using Object.keys(), and checking if each key exists in the first object using Array.prototype.every(), Object.prototype.hasOwnProperty().
In order to compare the values of the properties, we can simply use the strict equality operator (===). This will ensure that the values are not only equal but also of the same type.
If, instead, we want to use a custom function to determine value equality, we can simply replace the strict equality operator with the provided function. This function will receive the value of the property in both objects, as well as the key and the objects themselves.
If you want to compare two objects in both directions, you can create a Set of the keys of both objects and check if the size of the set is equal to the number of keys in each object. Then, you can use the same approach as before, except iterating over the keys of the set and checking if each key exists in both objects.
For simple value comparison, you can again use the strict equality operator (===).
For custom value comparison, you can use the same approach as before, using a custom function to determine value equality.

Code Snippets

const matches = (obj, source) =>
  Object.keys(source).every(
    key => obj.hasOwnProperty(key) && obj[key] === source[key]
  );

matches(
  { age: 25, hair: 'long', beard: true },
  { hair: 'long', beard: true }
); // true

matches(
  { hair: 'long', beard: true },
  { age: 25, hair: 'long', beard: true }
); // false
const matchesWith = (obj, source, fn) =>
  Object.keys(source).every(
    key =>
      obj.hasOwnProperty(key) &&
      fn(obj[key], source[key], key, obj, source)
  );

const isGreeting = val => /^h(?:i|ello)$/.test(val);
matchesWith(
  { greeting: 'hello' },
  { greeting: 'hi' },
  (a, b) => isGreeting(a) && isGreeting(b)
); // true
const matchesSymmetric = (a, b) => {
  const keysA = Object.keys(a),
    keysB = Object.keys(b);
  const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
  if (keys.size !== keysA.length || keys.size !== keysB.length) return false;

  return [...keys].every(
    key => a.hasOwnProperty(key) && b.hasOwnProperty(key) && a[key] === b[key]
  );
};

matchesSymmetric(
  { age: 25, hair: 'long', beard: true },
  { hair: 'long', beard: true }
); // false

matchesSymmetric(
  { hair: 'long', beard: true },
  { age: 25, hair: 'long', beard: true }
); // false

matchesSymmetric(
  { age: 25, hair: 'long', beard: true },
  { age: 25, hair: 'long', beard: true }
); // true

Context

From 30-seconds-of-code: match-object-properties

Revisions (0)

No revisions yet.