How can I check that two objects have the same set of property names?

后端 未结 7 1281
傲寒
傲寒 2020-11-28 06:04

I am using node, mocha, and chai for my application. I want to test that my returned results data property is the same \"type of object\" as one of my model objects (Very si

相关标签:
7条回答
  • 2020-11-28 06:06

    If you want to check if both objects have the same properties name, you can do this:

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

    In this way you are sure to check only iterable and accessible properties of both the objects.

    EDIT - 2013.04.26:

    The previous function can be rewritten in the following way:

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

    In this way we check that both the objects have the same number of properties (otherwise the objects haven't the same properties, and we must return a logical false) then, if the number matches, we go to check if they have the same properties.

    Bonus

    A possible enhancement could be to introduce also a type checking to enforce the match on every property.

    0 讨论(0)
  • 2020-11-28 06:06

    To compare two objects along with all attributes of it, I followed this code and it didn't require tostring() or json compar

    if(user1.equals(user2))
    {
    console.log("Both are equal");
    }

    e.

    0 讨论(0)
  • 2020-11-28 06:15

    If you are using underscoreJs then you can simply use _.isEqual function and it compares all keys and values at each and every level of hierarchy like below example.

    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
    

    If all the keys and values for those keys are same in both the objects then it will return true, otherwise return false.

    0 讨论(0)
  • 2020-11-28 06:21

    2 Here a short ES6 variadic version:

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

    A little performance test (MacBook Pro - 2,8 GHz Intel Core i7, Node 5.5.0):

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

    Results:

    objectsHaveSameKeys(x, y) // took  4996 milliseconds
    compareKeys(x, y)               // took 14880 milliseconds
    hasSameProps(x,y)               // after 10 minutes I stopped execution
    
    0 讨论(0)
  • 2020-11-28 06:24

    Here is my attempt at validating JSON properties. I used @casey-foster 's approach, but added recursion for deeper validation. The third parameter in function is optional and only used for testing.

    //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;
    
    }
    
    0 讨论(0)
  • 2020-11-28 06:29

    If you want deep validation like @speculees, here's an answer using deep-keys (disclosure: I'm sort of a maintainer of this small package)

    // 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);
    

    or with 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));
    
    0 讨论(0)
提交回复
热议问题