1

I'm attempting deep object comparison using recursion, but my function is returning undefined.

I know there are better ways to compare objects (IE JSON.Stringify()) but I'm not understanding why my function is returning undefined.

function deepObjCompare(obj1, obj2) {

  Object.keys(obj1).forEach((key) => {
    const key1 = obj1[key];
    const key2 = obj2[key];

    if (key2) {
      if (typeof key1 === "object" && key1 !== null) {
        deepObjCompare(key1, key2);
      } else if (key1 === key2) {
        return true;
      }
    }
    return false;
  });
}

const obj1 = {
  name: "Bill",
  address: {
    cityNow: "Paris",
    cityFuture: "NYC"
  },
  age: 39
};

const obj2 = {
  name: "Bill",
  address: {
    cityNow: "Paris",
    cityFuture: "NYC"
  },
  age: 39
};

const obj3 = {
  name: "Bob",
  address: "Paris",
  age: 39
};

console.log(deepObjCompare(obj1, obj3));

4
  • Possible duplicate: stackoverflow.com/q/33232823/633183 Commented Sep 26, 2018 at 17:51
  • You will want to use .every. Never use forEach Commented Sep 26, 2018 at 17:57
  • This program has a lot of complexity that is easily overlooked. I encourage you to see my answer to the above Q&A Commented Sep 26, 2018 at 17:57
  • 3
    JSON.stringify is not a proper way to compare objects, as they might be serialised in different order. Commented Sep 26, 2018 at 17:57

3 Answers 3

2

I see three main issues here:

  • deepObjCompare lacks a return statement, which is why it is implicitly returning undefined.
  • The .forEach method always returns undefined, so you'll want to change that to another method that will return an actual value. I think .every is what you're after here.
  • You do not return the result of your recursive call.

All together, that would change your snippet to the following:

function deepObjCompare(obj1, obj2) {

  return Object.keys(obj1).every((key) => { // Use .every and return the result!
    const key1 = obj1[key];
    const key2 = obj2[key];

    if (key2) {
      if (typeof key1 === "object" && key1 !== null) {
        return deepObjCompare(key1, key2); // Return the result of your recursive call!
      } else if (key1 === key2) {
        return true;
      }
    }
    return false;
  });
}

const obj1 = {
  name: "Bill",
  address: {
    cityNow: "Paris",
    cityFuture: "NYC"
  },
  age: 39
};

const obj2 = {
  name: "Bill",
  address: {
    cityNow: "Paris",
    cityFuture: "NYC"
  },
  age: 39
};

const obj3 = {
  name: "Bob",
  address: "Paris",
  age: 39
};

console.log(deepObjCompare(obj1, obj3)); // false
console.log(deepObjCompare(obj1, obj2)); // true

Sign up to request clarification or add additional context in comments.

Comments

2

You can't return from a forEach loop, and you have to return the recursive call:

function deepObjCompare(obj1, obj2) {

  let keys = Object.keys(obj1);
  return keys.every((key) => { // use a for-of loop instead of forEach
    const key1 = obj1[key];
    const key2 = obj2[key];

    if (key2) {
      if (typeof key1 === "object" && key1 !== null) {
         return deepObjCompare(key1, key2); // return the recursive call
      } else if (key1 === key2) {
        return true;
      }
    }
    return false;
  });
}

const obj1 = {name: "Bill",address: {cityNow: "Paris",cityFuture: "NYC"},age: 39};
const obj2 = {name: "Bill",address: {cityNow: "Paris",cityFuture: "NYC"},age: 39};
const obj3 = {name: "Bill",address: "Paris",age: 39};

console.log("Are Obj1 and Obj3 equal? ",deepObjCompare(obj1, obj3));
console.log("Are Obj1 and Obj2 equal? ",deepObjCompare(obj1, obj2));

Comments

-1

There are actually a number of things I see that are wrong with this implementation. But as to why it's returning undefined - that's because your function never actually returns anything. All your return statements are inside the function passed to forEach, and therefore do nothing with regard to the outer deepObjCompare.

1 Comment

Can someone please explain the down votes? I appreciate I didn't give a solution to comparing objects, and therefore it's not as good as other answers given. But my time was limited and it sounded like the OP just wanted to know why they were getting undefined, with a view to fixing it themselves. And I believe my answer is correct on that point. No hard feelings, I'm just relatively new to participating on SO and would like to learn from my mistakes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.