簡體   English   中英

如何檢查對象的鍵和深鍵是否相等,類似於lodash的isEqual?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM