如何检查两个对象具有相同的一组属性名称?(How can I check that two obje

2019-07-18 08:02发布

我使用的节点,摩卡和薛宝钗我的应用程序。 我想测试我的返回结果的数据属性是相同的“对象类型”为我的模型对象之一。 (非常相似,柴氏的instanceof)。 我只是想确认两个对象有相同的一组属性名称。 我特别不感兴趣的属性的实际值。

可以说我有模型人物像下面。 我想检查我的results.data拥有所有的期望模型做同样的性质。 所以在这种情况下,人具有firstName和lastName。

所以,如果results.data.lastNameresults.data.firstName都存在,那么它应该返回true。 如果任何一个不存在,它应该返回false。 奖金是,如果results.data有一个像results.data.surname任何附加属性,那么它会返回false,因为姓不存在的人。

该模型

function Person(data) {
  var self = this;
  self.firstName = "unknown";
  self.lastName = "unknown";

  if (typeof data != "undefined") {
     self.firstName = data.firstName;
     self.lastName = data.lastName;
  }
}

Answer 1:

你可以简单的序列数据,以检查是否相等:

data1 = {firstName: 'John', lastName: 'Smith'};
data2 = {firstName: 'Jane', lastName: 'Smith'};
JSON.stringify(data1) === JSON.stringify(data2)

这会给你喜欢的东西

'{firstName:"John",lastName:"Smith"}' === '{firstName:"Jane",lastName:"Smith"}'

作为一个功能...

function compare(a, b) {
  return JSON.stringify(a) === JSON.stringify(b);
}
compare(data1, data2);

编辑

如果你使用的柴像你说的,看看http://chaijs.com/api/bdd/#equal-section

编辑2

如果你只是要检查钥匙...

function compareKeys(a, b) {
  var aKeys = Object.keys(a).sort();
  var bKeys = Object.keys(b).sort();
  return JSON.stringify(aKeys) === JSON.stringify(bKeys);
}

应该这样做。



Answer 2:

2这里短ES6可变参数版本:

function objectsHaveSameKeys(...objects) {
   const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []);
   const union = new Set(allKeys);
   return objects.every(object => union.size === Object.keys(object).length);
}

一个小的性能测试 (的MacBook Pro - 2.8 GHz的英特尔酷睿i7,节点5.5.0):

var x = {};
var y = {};

for (var i = 0; i < 5000000; ++i) {
    x[i] = i;
    y[i] = i;
}

结果:

objectsHaveSameKeys(x, y) // took  4996 milliseconds
compareKeys(x, y)               // took 14880 milliseconds
hasSameProps(x,y)               // after 10 minutes I stopped execution


Answer 3:

如果您想检查两个对象具有相同的属性名称,你可以这样做:

function hasSameProps( obj1, obj2 ) {
  return Object.keys( obj1 ).every( function( prop ) {
    return obj2.hasOwnProperty( prop );
  });
}

var obj1 = { prop1: 'hello', prop2: 'world', prop3: [1,2,3,4,5] },
    obj2 = { prop1: 'hello', prop2: 'world', prop3: [1,2,3,4,5] };

console.log(hasSameProps(obj1, obj2));

这样,你一定要同时检查对象只可迭代和可访问性。

编辑- 2013年4月26日:

以前的功能,可以通过以下方式进行改写:

function hasSameProps( obj1, obj2 ) {
    var obj1Props = Object.keys( obj1 ),
        obj2Props = Object.keys( obj2 );

    if ( obj1Props.length == obj2Props.length ) {
        return obj1Props.every( function( prop ) {
          return obj2Props.indexOf( prop ) >= 0;
        });
    }

    return false;
}

通过这种方式,我们检查这两个对象具有相同的属性(否则的对象没有相同的属性,我们必须返回一个逻辑假),那么,如果该号码符合,我们去检查,如果他们有相同的属性。

奖金

一个可能的增强可能是还引入类型检查执行关于每个属性的匹配。



Answer 4:

如果你想要一个像@speculees深验证,这里使用的答案deep-keys (披露:我是那种这个小包裹的维护者)

// obj1 should have all of obj2's properties
var deepKeys = require('deep-keys');
var _ = require('underscore');
assert(0 === _.difference(deepKeys(obj2), deepKeys(obj1)).length);

// obj1 should have exactly obj2's properties
var deepKeys = require('deep-keys');
var _ = require('lodash');
assert(0 === _.xor(deepKeys(obj2), deepKeys(obj1)).length);

或者用chai

var expect = require('chai').expect;
var deepKeys = require('deep-keys');
// obj1 should have all of obj2's properties
expect(deepKeys(obj1)).to.include.members(deepKeys(obj2));
// obj1 should have exactly obj2's properties
expect(deepKeys(obj1)).to.have.members(deepKeys(obj2));


Answer 5:

这是我在验证JSON性质的尝试。 我用@凯西福斯特的做法,倒是递归进行更深入的验证。 在功能上的第三个参数是可选的,只用于测试。

//compare json2 to json1
function isValidJson(json1, json2, showInConsole) {

    if (!showInConsole)
        showInConsole = false;

    var aKeys = Object.keys(json1).sort();
    var bKeys = Object.keys(json2).sort();

    for (var i = 0; i < aKeys.length; i++) {

        if (showInConsole)
            console.log("---------" + JSON.stringify(aKeys[i]) + "  " + JSON.stringify(bKeys[i]))

        if (JSON.stringify(aKeys[i]) === JSON.stringify(bKeys[i])) {

            if (typeof json1[aKeys[i]] === 'object'){ // contains another obj

                if (showInConsole)
                    console.log("Entering " + JSON.stringify(aKeys[i]))

                if (!isValidJson(json1[aKeys[i]], json2[bKeys[i]], showInConsole)) 
                    return false; // if recursive validation fails

                if (showInConsole)
                    console.log("Leaving " + JSON.stringify(aKeys[i]))

            }

        } else {

            console.warn("validation failed at " + aKeys[i]);
            return false; // if attribute names dont mactch

        }

    }

    return true;

}


Answer 6:

如果你正在使用underscoreJs那么你可以简单地使用_.isEqual功能,它在每一个所有键和值,并像下面的例子层次的各个层面进行比较。

var object = {"status":"inserted","id":"5799acb792b0525e05ba074c","data":{"workout":[{"set":[{"setNo":1,"exercises":[{"name":"hjkh","type":"Reps","category":"Cardio","set":{"reps":5}}],"isLastSet":false,"index":0,"isStart":true,"startDuration":1469689001989,"isEnd":true,"endDuration":1469689003323,"speed":"00:00:01"}],"setType":"Set","isSuper":false,"index":0}],"time":"2016-07-28T06:56:52.800Z"}};

var object1 = {"status":"inserted","id":"5799acb792b0525e05ba074c","data":{"workout":[{"set":[{"setNo":1,"exercises":[{"name":"hjkh","type":"Reps","category":"Cardio","set":{"reps":5}}],"isLastSet":false,"index":0,"isStart":true,"startDuration":1469689001989,"isEnd":true,"endDuration":1469689003323,"speed":"00:00:01"}],"setType":"Set","isSuper":false,"index":0}],"time":"2016-07-28T06:56:52.800Z"}};

console.log(_.isEqual(object, object1));//return true

如果所有这些按键的键和值是两个对象相同,则它将返回true,否则返回false。



文章来源: How can I check that two objects have the same set of property names?