Какой самый простой способ проверить, совпадают ли ключи между двумя объектами? - PullRequest
0 голосов
/ 25 февраля 2019

при условии, что у вас есть два объекта с достаточным количеством вложений ...

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

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

Есть ли простой способ проверить, что все ключи совпадают между собой?

* Соответствие: оба объекта имеют одинаковые ключи в одном и том же вложенном месте, дополнительные ключи отсутствуют, поэтому objA и objB Match

Ответы [ 4 ]

0 голосов
/ 25 февраля 2019

Я думаю, что приведенный ниже код должен широко охватывать все типы объектов для решения.

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 compare 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
0 голосов
/ 25 февраля 2019

Рекомендую посмотреть на реализацию isEqual из lodash , https://lodash.com/docs/4.17.11#isEqual

0 голосов
/ 25 февраля 2019

Это довольно похоже на ответ Нины Шольц, с достаточным количеством различий в мыслях, чтобы сделать его интересной альтернативой:

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))

Это вполне может дать сбой циклическим структурам.Я не продумал это до конца.

0 голосов
/ 25 февраля 2019

В простом Javascript вы можете получить ключи, сравнить длину и перебрать ключи и проверить, являются ли значения объектами.

function compareKeys(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'
                ? compareKeys(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(compareKeys(objA, objB));
console.log(compareKeys(objA, objC));
console.log(compareKeys({ a: {} }, { a: "test" }));
console.log(compareKeys({ a: "test" }, { a: {} }));
console.log(compareKeys({ a: { b: "new str" } }, { a: "test" }));
...