1

I have two objects:

const have = {
  a: true,
  b: {
    c: true,
    d: true
  }
};

const need = {
  a: false,
  b: {
    c: true,
    d: false
  }
};

I need to find in the "need" obj, if there are at least one positive match (true) with the "have" obj. In this case,they match in b.c, since both are true.

Any ideas how I should face this? maybe first parse to an array? Loop the obj?

Update:

The 'need' obj, does not always contains all the same keys. It might have fewer, but not different.

example:

const need = {
  b: {
    c: true,
  }
};

2 Answers 2

1

If the keys and object structures always match up, you can do a recursive check of the keys/values:

const have = {
  a: true,
  b: {
    c: true,
    d: true
  }
};

const need = {
  a: false,
  b: {
    c: true,
    d: false
  }
};

function objectsHaveMatch(obj1, obj2) {
  return Object.entries(obj1).some(([key, obj1Val]) => {
    if (!obj2[key]) return false;
    if (typeof obj1Val !== 'boolean') return objectsHaveMatch(obj1Val, obj2[key]);
    return obj1Val === true && obj2[key] === true;
	});
}

const atLeastOneMatch = objectsHaveMatch(have, need);
console.log(atLeastOneMatch);

Also works with more complicated structures:

const have = {
  a: true,
  b: {
    c: false,
    d: true,
    foo: {
      q: false,
      w: false,
      e: false,
      r: {
        t: true
      }
    }
  }
};

const need = {
  a: false,
  b: {
    c: true,
    d: false,
    foo: {
      q: true,
      w: true,
      e: true,
      r: {
        t: false
      }
    }
  }
};

function objectsHaveMatch(obj1, obj2) {
  return Object.entries(obj1).some(([key, obj1Val]) => {
    if (!obj2[key]) return false;
    if (typeof obj1Val !== 'boolean') return objectsHaveMatch(obj1Val, obj2[key]);
    return obj1Val === true && obj2[key] === true;
	});
}

const atLeastOneMatch = objectsHaveMatch(have, need);
console.log(atLeastOneMatch);

Snippet example with missing properties:

const have = {
  a: true,
  b: {
    c: true,
    d: true,
    foo: {
      q: false,
      w: false,
      e: false,
      r: {
        t: true
      }
    }
  }
};

const need = {
  b: {
    c: true,
  }
};

function objectsHaveMatch(obj1, obj2) {
  return Object.entries(obj1).some(([key, obj1Val]) => {
    if (!obj2[key]) return false;
    if (typeof obj1Val !== 'boolean') return objectsHaveMatch(obj1Val, obj2[key]);
    return obj1Val === true && obj2[key] === true;
	});
}

const atLeastOneMatch = objectsHaveMatch(have, need);
console.log(atLeastOneMatch);

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

3 Comments

I was doing the exact same thing 😂
@MarianoZunino Just requires a one-line change: if (!obj2[key]) return false; see edit
@CertainPerformance Amazing! Working like a charm. I will investigate how that magic is works :)
0

Similar approach to the accepted answer, except the below is slightly more optimised for the OP's specific use case, assuming the data is 'imitative' and compared values are either an object or 'truthy'.

const have = { a: true, b: { c: true, d: true } };
const need = { b: { c: true } };

const hn = (h, n) => // 'have/need' iterator
  Object.keys(n).some(i => // at least one truthy 'need':
    typeof n[i] === 'object' && hn(h[i], n[i]) // recursive on object
    || n[i] && n[i] === h[i]); // or both h & n are equal and truthy


const has = hn(have, need);
console.log(has);

Comments

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.