检查所有顶级对象是否具有相同的属性

时间:2015-05-06 23:44:40

标签: javascript node.js

这是一些JSON:

{
  "environments":{

    "production":{
      "zmq_config":{
        "host":"*",
        "port":"7676"
      },
      "redis_server_config":{
        "host":"localhost",
        "port":"26379"
      }
    },

    "dev_remote":{
      "zmq_config":{
        "host":"*",
        "port":"5555"
      },
      "redis_server_config":{
        "host":"localhost",
        "port":"16379"
      }
    },

    "dev_local":{
      "zmq_config":{
        "host":"*",
        "port":"5555"
      },
      "redis_server_config":{
        "host":"localhost",
        "port":"6379"
      }
    }
  }
}

我想在我的测试套件中创建一个测试,确保所有属性都具有相同的补充属性。

例如,对于" environment"的每个属性,我想检查它们是否具有相同的属性;在这种情况下他们这样做 - 他们都有2个属性" zmq_config"和" redis_server_config"。现在我想做至少一个级别的检查。对于属性" zmq_config"和" redis_server_config",我想检查它们是否具有相同的属性" host"和" port"。

你明白了。

是否有可以执行此操作的库?是否有某种JavaScript身份运算符检查这一点,只是查看顶级对象?

现在我能想到的最简单的方法就是迭代并查看具有相同名称的每个属性(假设具有相同名称的属性位于对象层次结构中的相同位置),然后只是看看他们是否有相同的子属性。

Underscore.js是最佳选择吗?看起来Underscore有这个功能可能有用:

_.isEqual(obj1, obj2);
从我的研究中看来,这似乎是最好的候选人:

_.isMatch(obj1,obj2);

3 个答案:

答案 0 :(得分:1)

对于要测试的每个对象,可以使用Object.keys函数提取对象的键,然后比较它们,因为您只想知道属性是否等于,值不重要。

然后,当你提取每个对象的键时,可以使用lodash提供的_.isEqual函数而不是下划线进行比较(通常lodash具有更好的性能)。

要尽可能自动化,您应该创建一个递归函数来提取密钥并进行比较。

答案 1 :(得分:1)

快速破解这个,但它应该对你公正。如果所有嵌套对象键都匹配,则返回true。在每个级别,它检查密钥数组是否与其他对象的密钥数组匹配,并且它以递归方式执行。

function keysMatch(data1,data2){     var result = null;

function check(d1, d2) {
    if (result === false) {
        return false;
    }
    if (_.isObject(d1) && _.isObject(d2)) {
        if (allArraysAlike([_.keys(d1), _.keys(d2)])) {
            result = true;
            _.forOwn(d1, function (val, key) {
                check(d1[key], d2[key]);
            });
        } else {
            result = false;
        }
    }
    return result;
  }

  return check(data1, data2);
}

function allArraysAlike(arrays) {
    return _.all(arrays, function (array) {
        return array.length == arrays[0].length && _.difference(array, arrays[0]).length == 0;
    });
}

console.log(keysMatch(json1, json2));

<强> http://jsfiddle.net/baafbjo8/2/

答案 2 :(得分:1)

如果你想要一个简单的真/假答案,那么可以从基本的javascript创建一个简单的函数。

下面的功能使用了ES5功能,但使用普通循环的代码不会多得多(并且启动运行速度快,而不是速度慢)。

/**
 *  @param {Object} obj - Object to check properties of
 *  @param {Array} props - Array of properties to check
 *  @returns {boolean}
**/
function checkProps(obj, props) {
  // List of members of obj
  var memberNames  = Object.keys(obj);
  // Use keys of first object as base set
  var baseKeys = Object.keys(obj[memberNames[0]]);

  // Check every object in obj has base set of properties
  // And each sub-object has props properties
  return memberNames.every(function (memberName) {

    // Get member
    var member = obj[memberName];

    // Get keys of this member
    var memberKeys = Object.keys(member);

    // First check that member has same keys as base, then that each sub-member
    // has required properties
    return memberKeys.length == baseKeys.length &&
           baseKeys.every(function(key) {
             return member.hasOwnProperty(key) &&

                    // Check sub-member properties
                    props.every(function(prop) {
                      return member[key].hasOwnProperty(prop);
                    });
           });
  });
}

console.log(checkProps(env,['host','port']));

对于EcmaScript ed 4兼容性,需要Array.prototype.everyObject.keys的填充。