【发布时间】:2018-05-30 18:50:10
【问题描述】:
所以我处于一个独特的情况,我有两个对象,我需要比较所述对象上的键以确保它们与默认对象匹配。这是我正在尝试做的一个示例:
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 并强制更新数据库,即使没有任何键发生更改。为了解决这个问题,我需要一种方法来比较对象上的 键,而不是任何键和数据。
这样,如果我向 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);
是否可以不用放空数组也能使用?
【问题讨论】:
标签: javascript node.js underscore.js lodash