Итак, я нахожусь в уникальной ситуации, когда у меня есть два объекта, и мне нужно сравнить ключи на указанных объектах, чтобы убедиться, что они соответствуют объекту по умолчанию.Вот пример того, что я пытаюсь сделать:
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);
Возможно ли использовать его без необходимости ставить пустоймассив тоже?