Как проверить, равны ли ключи объекта и глубокие ключи, как в lodash isEqual? - PullRequest
0 голосов
/ 30 мая 2018

Итак, я нахожусь в уникальной ситуации, когда у меня есть два объекта, и мне нужно сравнить ключи на указанных объектах, чтобы убедиться, что они соответствуют объекту по умолчанию.Вот пример того, что я пытаюсь сделать:

const _ = require('lodash');

class DefaultObject {
  constructor(id) {
    this.id = id;
    this.myobj1 = {
      setting1: true,
      setting2: false,
      setting3: 'mydynamicstring'
    };
    this.myobj2 = {
      perm1: 'ALL',
      perm2: 'LIMITED',
      perm3: 'LIMITED',
      perm4: 'ADMIN'
    };
  }
}

async verifyDataIntegrity(id, data) {
  const defaultData = _.merge(new DefaultObject(id));
  if (defaultData.hasOwnProperty('myoldsetting')) delete defaultData.myoldsetting;
  if (!_.isEqual(data, defaultData)) {
    await myMongoDBCollection.replaceOne({ id }, defaultData);
    return defaultData;
  } else {
    return data;
  }
}

async requestData(id) {
  const data = await myMongoDBCollection.findOne({ id });
  if (!data) data = await this.makeNewData(id);
  else data = await this.verifyDataIntegrity(id, data);
  return data;
}

Позвольте мне объяснить.Во-первых, у меня есть объект по умолчанию, который создается каждый раз, когда пользователь впервые использует сервис.Затем этот объект изменяется в соответствии с их индивидуальными настройками.Например, они могли бы изменить «setting1» на false, а «perm2» на «ALL».

Теперь более старая версия моего объекта по умолчанию имела свойство myoldsetting.Я не хочу, чтобы в новых продуктах была эта настройка, поэтому каждый раз, когда пользователь запрашивает свои данные, я проверяю, имеет ли их объект настройку «myoldsetting», и, если это так, удаляет его.Затем, чтобы предотвратить ненужные обновления (поскольку это называется каждый раз, когда пользователь хочет получить свои данные), я проверяю, совпадает ли это с новым объектом по умолчанию.

Но это не работаетпотому что, если пользователь изменил настройку, он всегда будет возвращать false и принудительно обновлять базу данных, даже если ни один из ключей не изменился.Чтобы это исправить, мне нужен метод сравнения keys на объекте, а не любых ключей и данных.

Таким образом, если я добавлю новую опцию в DefaultObject, скажем, 'perm5 'установлен в' ADMIN ', тогда он обновит объект пользователя.Но если их объект имеет те же ключи (он обновлен), то продолжайте в течение дня.

Мне нужно, чтобы это сравнение было глубоким, на случай, если я добавлю новое свойство, например, в myobj1,Если я сравню только ключи основного уровня (id, myobj1, myobj2), он не узнает, добавил ли я новый ключ в myobj1 или myobj2.

Я извиняюсь, если это не имеет смысла, этоочень специфическая ситуацияЗаранее спасибо, если вы можете помочь.

~~~~ РЕДАКТИРОВАТЬ ~~~~

Хорошо, так что я на самом деле придумала функцию, которая делает именно то, что мне нужно,Вопрос в том, что я хотел бы минимизировать его, чтобы он не был таким большим.Кроме того, я не могу найти способ проверить, является ли объект объектом, даже если он нулевой.Этот ответ не очень помог.

Вот моя рабочая функция.

function getKeysDeep(arr, obj) {
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === 'object') {
      arr = getKeysDeep(arr, obj[key]);
    }
  });
  arr = arr.concat(Object.keys(obj));
  return arr;
}

Использование

getKeysDeep([], myobj);

Возможно ли использовать его без необходимости ставить пустоймассив тоже?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Хорошо, так что я действительно придумал функцию, которая делает именно то, что мне нужно.Вопрос в том, что я хотел бы минимизировать его, чтобы он не был таким большим.Кроме того, я не могу найти способ проверить, является ли объект объектом, даже если он нулевой.

В конце концов, это работает для меня.Если бы кто-нибудь смог улучшить его, это было бы здорово.

function getKeysDeep(obj, arr = []) {
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === 'object' && !Array.isArray(obj[key]) && obj[key] !== null) {
      arr = this.getKeysDeep(obj[key], arr);
    }
  });
  return arr.concat(Object.keys(obj));
}
getKeysDeep(myobj);
0 голосов
/ 30 мая 2018

Итак, если я вас правильно понимаю, вы бы хотели сравнить ключи двух объектов, верно?

Если это так, вы можете попробовать что-то вроде этого:

function hasSameKeys(a, b) {
  const aKeys = Object.keys(a);
  const bKeys = Object.keys(b);
  return aKeys.length === bKeys.length && !(aKeys.some(key => bKeys.indexOf(key) < 0));
}

Object.keys (x) даст вам все ключи собственных свойств объектов.

indexOf вернет -1, если значение не находится в массиве, к которому вызывается indexOf.

Некоторые вернутся, как только любой элемент массива (aKeys) оценивается как true в обратном вызове.В этом случае: если один из ключей не включен в другой массив (indexOf(key) < 0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...