-1

I have an object with some very specific keys. How can I check if another object has exactly the same keys? For example:

let myOb = {
  name: "somebody",
  class: {
    number: 9,
    section: "C"
  },
  address: {
    house: 22,
    street: "Eg street"
    PIN: 7893
  }
}

if (newOb.containsAll(myOb)) { // this is just a replacement function
  // do stuff
}

I want to match the newOb to myOb and see if they have the exact keys. So, newOb should have a name, class, address; newOb.class should have a number and section; newOb.address should have a house, street and PIN.

I am already aware of hasOwnProperty(). I want to know if there is a easier way to do this were multiple keys are involved.

Rak Laptudirm
  • 174
  • 2
  • 13
  • Please [**search**](/search?q=%5Bjs%5D+check+object+has+property) before posting. More about seraching [here](/help/searching). See the linked question as well as https://stackoverflow.com/questions/27509/detecting-an-undefined-object-property/416327?r=SearchResults&s=9|163.3307#416327 and [`typeof`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof). – T.J. Crowder Mar 22 '21 at 17:01
  • @T.J.Crowder I had seen that already. I wanted to know if there was a easier way to do this were multiple keys are involved. Please let me know if there is. – Rak Laptudirm Mar 22 '21 at 17:04

1 Answers1

1

You can compare the two object's (recursive) key sets.

const
  myObjA = {
    name: "somebody",
    class: { number: 9, section: "C" },
    address: { house: 22, street: "Eg street", PIN: 7893 }
  },
  myObjB = {
    name: "somebody else",
    class: { number: 1, section: "A" },
    address: { house: 11, street: "Another st", PIN: 0000 }
  };

// Adapted from: https://stackoverflow.com/a/53620876/1762224
const gatherKeys = obj => {
  const
    isObject = val => typeof val === 'object' && !Array.isArray(val),
    addDelimiter = (a, b) => a ? `${a}.${b}` : b,
    paths = (obj = {}, head = '') => Object.entries(obj)
      .reduce((product, [key, value]) =>
        (fullPath => isObject(value)
          ? product.concat(paths(value, fullPath))
          : product.concat(fullPath))
        (addDelimiter(head, key)), []);
  return new Set(paths(obj));
};

const
  diff = (a, b) => new Set(Array.from(a).filter(item => !b.has(item))),
  equalByKeys = (a, b) => diff(gatherKeys(a), gatherKeys(b)).size === 0;

console.log(equalByKeys(myObjA, myObjB));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132