最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Whats the easiest way to check if keys match between two objects? - Stack Overflow

programmeradmin1浏览0评论

assuming you have two objects that have a decent amount of nesting...

const objA = {
  one: {
    a: 10,
    b: 'string1',
    c: {
      d: 10
    }
  },
  two : 'string1'
}

const objB = {
  one: {
    a: 20,
    b: 'string2',
    c: {
      d: 20
    }
  },
  two : 'string2'
}

Is there an easy way to check that all the keys match between them?

*Match: both object have the same keys in the same nested location, there are no extra keys, so objA and objB Match

assuming you have two objects that have a decent amount of nesting...

const objA = {
  one: {
    a: 10,
    b: 'string1',
    c: {
      d: 10
    }
  },
  two : 'string1'
}

const objB = {
  one: {
    a: 20,
    b: 'string2',
    c: {
      d: 20
    }
  },
  two : 'string2'
}

Is there an easy way to check that all the keys match between them?

*Match: both object have the same keys in the same nested location, there are no extra keys, so objA and objB Match

Share Improve this question asked Feb 25, 2019 at 17:25 lonewarrior556lonewarrior556 4,5193 gold badges32 silver badges58 bronze badges 1
  • you can think like paring Object.keys() recursively for both the object. – Guru1988 Commented Feb 25, 2019 at 17:34
Add a ment  | 

4 Answers 4

Reset to default 5

In plain Javascript, you could get the keys, pare the length and iterate the keys and check if the values are objects.

function pareKeys(a, b) {
    var keysA = Object.keys(a),
        keysB = Object.keys(b);
    return keysA.length === keysB.length
        && keysA.every(k => b.hasOwnProperty(k) && (
            a[k] && typeof a[k] === 'object' ||
            b[k] && typeof b[k] === 'object'
                ? pareKeys(a[k], b[k])
                : true));
}

const
    objA = { one: { a: 10, b: 'string1', c: { d: 10 } }, two : 'string1' },
    objB = { one: { a: 20, b: 'string2', c: { d: 20 } }, two : 'string2' },
    objC = { one: { a: 20, b: 'string2', c: { d: 20, e: false } }, two : 'string2' };

console.log(pareKeys(objA, objB));
console.log(pareKeys(objA, objC));
console.log(pareKeys({ a: {} }, { a: "test" }));
console.log(pareKeys({ a: "test" }, { a: {} }));
console.log(pareKeys({ a: { b: "new str" } }, { a: "test" }));

I think below code should extensively cover all type of objects for solution.

const doAllKeysMatch = (obj1, obj2) => {

  if (typeof obj1 != 'object' && typeof obj1 != 'object') {
    return true;
  }

  if (typeof obj1 == 'object' && typeof obj1 == 'object') {
    // if both are object types pare all keys
    let obj1Keys = Object.keys(obj1);
    let obj2Keys = Object.keys(obj2);

    return (obj1Keys.length == obj2Keys.length) && obj1Keys.every(key => obj2Keys.includes(key) && doAllKeysMatch(obj1[key], obj2[key]))

  }

  /*
    if only one is of object type check if it doesnt have any keys.
    if empty object is there then return true which means "abc" and {} have same keys
  */

  if ((typeof obj1 == 'object') && (Object.keys(obj1).length < 1)) {
      return true
  }

  return Object.keys(obj2).length < 1;
}

console.log(doAllKeysMatch("abc", "dfg")) // true
console.log(doAllKeysMatch("abc", {})) // true
console.log(doAllKeysMatch({a: "test"}, {a: {}})) // true
console.log(
  doAllKeysMatch(
    { 
      a: 10, 
      b: 'string1', 
      c: { d: 10 }, 
      two : 'string1' 
    }, 
    {
      a: 10, 
      b: 'string1', 
      c: { d: false },
      two : 'string2'
    }
  )) // true

This is fairly similar to the answer from Nina Scholz, with just enough differences in thoughts to make it an interesting alternative:

const matchingStructure = (a, b, ak = Object.keys(a), bk = Object.keys(b)) => 
  !(typeof a == 'object' && typeof b == 'object') ||
  ( ak.length === bk.length &&
    ak.every(k => k in b) &&
    ak.every(k => matchingStructure(a[k], b[k]))
  )


const objA = {one: {a: 10, b: "string1", c: {d: 10}}, two: "string1"}
const objB = {one: {a: 20, b: "string2", c: {d: 20}}, two: "string2"}
const objC = {one: {a: 30, b: "string3", c: {d: 30}, e: true}, two: "string3"}

console.log(matchingStructure(objA, objB))
console.log(matchingStructure(objA, objC))

It could well fail on cyclic structures. I haven't thought that through.

I remend to look at the implementation of isEqual from lodash, https://lodash./docs/4.17.11#isEqual

发布评论

评论列表(0)

  1. 暂无评论