如何检查对象的键和深键是否相等,类似于lodash的isEqual?

时间:2018-05-30 18:50:11

标签: javascript node.js underscore.js lodash

所以我处于一个独特的情况,我有两个对象,我需要比较所述对象上的键,以确保它们与默认对象匹配。以下是我尝试做的一个例子:

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;
}

让我解释一下。首先,我有一个默认对象,每次用户首次使用该服务时都会创建该对象。然后,该对象被修改为其自定义设置。例如,他们可以改变设置1'在改变perm2'时变得虚假成为' ALL'。

现在,我的默认对象的旧版本曾经有一个名为' myoldsetting'的属性。我不希望新产品具有此设置,因此每次用户请求他们的数据时,我都会检查他们的对象是否具有设置' myoldsetting',如果有,请将其删除。然后,为了防止不必要的更新(因为每次用户想要他们的数据时都称为),我会检查它是否与新的默认对象相同。

但是这不起作用,因为如果用户更改了设置,它将始终返回false并强制进行数据库更新,即使没有任何键已更改。要解决这个问题,我需要一种方法来比较对象上的,而不是任何键和数据。

这样,如果我向DefaultObject添加一个新选项,比如说,' perm5'设置为' ADMIN',然后它将更新用户的对象。但是,如果他们的对象具有相同的键(它是最新的),那么继续你的一天。

我需要将此比较深入,以防我在其中添加新属性,例如myobj1。如果我只比较主级键(id,myobj1,myobj2),它就不知道我是否在myobj1或myobj2中添加了一个新键。

如果这没有意义,我道歉,这是一个非常具体的情况。如果您能提供帮助,请提前致谢。

~~~~ EDIT ~~~~

好吧,所以我实际上想出了一个完全符合我需要的功能。问题是,我想缩小它以使它不那么大。此外,我似乎找不到一种方法来检查一个项目是否是一个对象,即使它是空的。这个答案非常有用。

这是我的工作职能。

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 :(得分:1)

所以,如果我理解你正确,你想比较两个对象的键,对吗?

如果是这种情况,你可以尝试这样的事情:

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

答案 1 :(得分:0)

好吧,所以我实际上想出了一个完全符合我需要的功能。问题是,我想缩小它以使它不那么大。此外,我似乎找不到一种方法来检查一个项目是否是一个对象,即使它是空的。

最后,这对我有用。如果有人能改进它那就太棒了。

Library                Process
Suite Setup            Open Connection And Log In
Suite Teardown         Close Connection

    *** Test Cases ***
    Capturing The Traffic Flow
        ${tcpdump}=    Write  nohup sudo tcpdump -v -U host ${public_ip_gateway} -w ${TCPDUMPFILE} &
        Log            ${tcpdump}       console=${True}
        ${ping_out}=   Execute Command  ping -c 15 8.8.8.8      return_stdout=True
        Log            ${ping_out}          console=${True}