[英]How to check if an object's keys and deep keys are equal, similar to lodash's isEqual?
因此,我處於一個獨特的情況下,我有兩個對象,並且我需要比較所述對象上的鍵,以確保它們與默認對象匹配。 這是我要執行的操作的一個示例:
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;
}
讓我解釋。 首先,我有一個默認對象,每次用戶首次使用該服務時都會創建一個默認對象。 然后,將該對象修改為其自定義設置。 例如,當將“ perm2”更改為“ ALL”時,他們可以將“ setting1”更改為false。
現在,我的默認對象的舊版本曾經擁有一個名為“ myoldsetting”的屬性。 我不希望較新的產品具有此設置,因此每次用戶請求數據時,我都會檢查其對象是否具有“ myoldsetting”設置,如果有,請將其刪除。 然后,為防止不必要的更新(因為每次用戶需要其數據時都會調用此更新),我檢查它是否與新的默認對象相等。
但這是行不通的,因為即使用戶沒有更改任何鍵,如果用戶更改了設置,它將始終返回false並強制更新數據庫。 為了解決這個問題,我需要一種比較對象上的鍵而不是任何鍵和數據的方法。
這樣,如果我向DefaultObject添加新選項,例如將'perm5'設置為'ADMIN',則它將更新用戶的對象。 但是,如果它們的對象具有相同的鍵(它是最新的),則可以繼續進行。
我需要進行比較,以防萬一我在例如myobj1中添加新屬性。 如果僅比較主級鍵(id,myobj1,myobj2),則不會知道是否將新鍵添加到myobj1或myobj2中。
抱歉,這是非常特殊的情況。 如果您能提供幫助,請先謝謝。
~~~~編輯~~~~
好吧,所以我實際上提出了一個功能,該功能完全可以滿足我的需求。 問題是,我想縮小它,以免它不那么大。 此外,即使它為null,我似乎也找不到找到檢查項目是否為對象的方法。 這個答案不是很有幫助。
這是我的工作職能。
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);
是否可以使用它而不必放入空數組?
因此,如果我對您的理解正確,那么您想比較兩個對象的鍵,對嗎?
如果是這種情況,您可以嘗試如下操作:
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的數組中,則indexOf將返回-1。
數組中的任何元素(aKeys)在回調中評估為true時,將立即返回一些。 在這種情況下:如果另一個數組中未包含任何鍵( indexOf(key) < 0
)
好吧,所以我實際上提出了一個功能,該功能完全可以滿足我的需求。 問題是,我想縮小它,以免它不那么大。 此外,即使它為null,我似乎也找不到找到檢查項目是否為對象的方法。
最后,這對我有用。 如果有人可以改善它,那就太好了。
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.