lalaland4545
lalaland4545

Reputation: 33

Comparing two objects properties but not working propery

Here is my code. I know it's not entirely strict but please shed some light on why the let...in does not work properly here.

const object1 = {here: 1, object: 3};
const obj = {here: 1, object: 2};

function comp(a, b) {
  if (typeof a == typeof b) {
    let arra = Object.keys(a);
    let arrb = Object.keys(b);
    for (let key in arra){
      if (a[key] == b[key]) return true
    }
        return false
  }
}

console.log(comp(obj, object1))

The above prints true but it is supposed to print false

Upvotes: 3

Views: 121

Answers (5)

Nick Parsons
Nick Parsons

Reputation: 50684

You're getting true because you return true in your for loop whenever a key value from one object equals the key-value pair of another object. So when your code sees the here property, it will return true, thus stopping your function from running any further code.

You need to remove this check, and only return false in your for loop, such that your for loop will only complete if it never returns (ie: all key-value pairs are equal).

Moreover, the for..in loop will loop over the keys in an object, so, there is no need to get the keys of your objects (using Object.keys) into an array (as then you'll be looping over the keys of an array (ie: the indexes)).

However, with that being said, you can use Object.keys to help with another issue. You can use it to get the number of properties in both objects, as you know the two objects are not the same if they don't have the same number of properties in them

See example below:

const object1 = {
  here: 1,
  object: 3
};
const obj = {
  here: 1,
  object: 3
};

function comp(a, b) {
  if (typeof a == typeof b) {
    if(Object.keys(a).length !== Object.keys(b).length) {
      return false; // return false (stop fruther code execution)
    }
  
    for (let key in a) { // loop through the properties of larger object (here I've chosen 'a') - no need for Object.keys
      if (a[key] != b[key]) 
        return false; // return false (stops any further code executing)
    }
    return true; // we only reach this point if the for loop never returned false
  }
  return false; // we reach this point when the two types don't match, and so we can say they're not equal
}

console.log(comp(obj, object1))

Upvotes: 5

Sohan
Sohan

Reputation: 66

Array.prototype.some() function can be used as below:

const object1 = {here: 1, object: 3, r:4};
const obj = {here: 1, r:4, object: 3};

function comp(a, b) {
  if (typeof a == typeof b) {
    let arra = Object.keys(a);
    return !arra.some(key => { return a[key] != b[key] })
  }
}

console.log(comp(obj, object1))

Upvotes: 0

Almog Gabay
Almog Gabay

Reputation: 135

Here is your problem:

for (let key in arra){
      if (a[key] == b[key]) return true
    }
        return false
  }

You should perform the exact opposite while iterating through the object:

for (let key in a){ // a not arra
      if (a[key] !== b[key]) return false
    }
        return true
  }

And ommit these lines:

let arra = Object.keys(a);
let arrb = Object.keys(b);

Upvotes: 1

MauriceNino
MauriceNino

Reputation: 6747

You need to check for actual values and not property names.

Also, you need to check if b has more properties than a, because if it is the same, but has one property more, it will still output true.

const tester = {here: 1, object: 3};
const obj1 = {here: 1, object: 2};
const obj2 = {here: 1, object: 3};
const obj3 = {here: 1, object: 3, test: 1};
const obj4 = {here: 1, test: 1};

function comp(a, b) {
  if (typeof a == typeof b && Object.keys(a).length == Object.keys(b).length) { // Check for the length of the keys array, because if the length is different, they might have different properties
    // Dont use Object.keys here. You don't need the keys, you need the objects
    for (let key in a){
      if (a[key] != b[key]) 
        return false; // If one key property of a does not match b, return false
    }
    return true; // If nothing returns false, return true
  }
  return false; // If they are not the same type, return false
}

console.log(comp(tester, obj1))
console.log(comp(tester, obj2))
console.log(comp(tester, obj3))
console.log(comp(tester, obj4))

Upvotes: 1

nicholaswmin
nicholaswmin

Reputation: 22949

You should use for..of (or just a plain old for) instead of for..in which is only used on Objects. You're reading array indices right now, not actual key names. Object.keys returns an Array of key names, not an Object.

Also stop returning early; Right now you return immediately after the first key check.

Upvotes: 1

Related Questions