I want to compare two json objects excluding one of the keys from it

I have two objects x,y and i want to compare both of these excluding one of the keys “c”

let x = {a: 5, b: 6, c: "string"}
let y = {a: 5, b: 8, c: "string"}

How i am trying to compare it is –

JSON.stringify(x) === JSON.stringify(y)

Above works but it will compare all keys I want to exclude c in comparison here. What’s the best way to achieve this ?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The following code obtains all the keys from object x, removes c from the list, and then performs the comparison.

let x = { a: 5, b: 6, c: "string" };
let y = { a: 5, b: 6, c: "another string" };

console.log(
  Object.keys(x)
    .filter((key) => key !== "c")
    .every((key) => x[key] === y[key])
);

Method 2

array.sort requires a comparator function. You can use the exact same thing here

function myObjComparator (x, y) {
  if (x.a != y.a) return y.a - x.a;
  return y.b - x.b;
}

Method 3

Generally, I would NOT stringify objects in order to compare them.
The reason is quite simple and is that you MUST to be sure that the order of the members are the same, otherwise the result won’t be correct.

Ex:

// objects are equals
const y = { a: '1', b: '2' }
const x = { b: '2', b: '1' }
// but result is not what you expect
JSON.stringify(x) === JSON.stringify(y) // false

But, if you can ensure that the order of the members is always the same, stringify is fast and a good option.

You can use the spread syntax in order to avoid the “c” property

const remappedX = { ...x, c: undefined };
const remappedY = { ...y, c: undefined };
JSON.stringify(remappedX) === JSON.stringify(remappedY); // true

Or alternatively

const allowedKeys = Object.keys(x).filter((k) => k !== 'c');
JSON.stringify(x, allowedKeys) === JSON.stringify(y, allowedKeys);

More generic method is to loop over Object key or alternatively to entries

for(const key of Object.keys(x)) {
   if (key === 'c') {
      continue;
   }
   if (x[key] !== y[key]) {
         return false;
   }
}
return true;

But, if your object is nested, you need to use a deep equality algorithm, which is of course slower.

More generic answer has been given here

Method 4

What about this?

JSON.stringify(x, ['a','b']) === JSON.stringify(y, ['a','b']);

better solution:

function replacer(key, value) {
  // Filtering out properties
  if (key === 'c') {
    return undefined;
  }
  return value;
}
JSON.stringify(x, replacer) === JSON.stringify(y, replacer);

correct better solution:

const filterKeys = (obj) => Object.keys(y).filter(k => k !== 'c').sort()
JSON.stringify(x, filterKeys(x)) === JSON.stringify(y, filterKeys(y));

Method 5

Using ternary operator to compare both the objects.

Demo :

let x = {a: 5, b: 6, c: "string"};
let y = {a: 5, b: 8, c: "string"};

function compare(obj1, obj2) {
  return (obj1.a != obj2.a) ? false : (obj1.b != obj2.b) ? false : true;
}

console.log(compare(x, y));

By deleting the unwanted properties and then compare using JSON.stringify()

Demo :

let x = {a: 5, b: 6, c: "string"};
let y = {a: 5, b: 8, c: "string"};

delete x.c;
delete y.c;

console.log(JSON.stringify(x) === JSON.stringify(y));

Method 6

Here is a solution

const x = {a: 5, b: 8, c: "string1", d: {e: 9}}
const y = {a: 5, b: 8, c: "string2", d: {e: 9}}

const compare = (obj1, obj2, except = []) => {
    
    if (Object.keys(obj1).length < Object.keys(obj2).length) {
        [obj1, obj2] = [obj2, obj1];
    }
    
    for (const obj1Key in obj1) {
        if (except.includes(obj1Key)) continue;

        if (!obj2.hasOwnProperty(obj1Key)) return false;

        if (typeof obj1[obj1Key] === 'object') {
            if (typeof obj2[obj1Key] !== 'object') return false;
            
            const isEqual = compare(obj1[obj1Key], obj2[obj1Key]);
            
            if (isEqual) continue
            
            return false;
        }

        if (obj1[obj1Key] !== obj2[obj1Key]) return false;
    }
    
    return true;
}

console.log(compare(x, y, ['c']));

Method 7

Thanks everyone for quick responses on my question but below was an easy method from which I could implement the above logic

import omit from "lodash/omit";
import isEqual from "lodash/isEqual";

let x = {a: 5, b: 6, c: "string"},
y = {a: 5, b: 8, c: "string"}

result = isEqual(omit(x, ['c']), omit(y, ['c']))


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x