2017-01-23 106 views
3

的问题是相似的:How can I check that two objects have the same set of property names?但只有一个区别的JavaScript:深检查对象具有相同的密钥

我要检查:

var objOne = {"a":"one","b":"two","c":{"f":"three_one"}}; 
var objTwo = {"a":"four","b":"five","c":{"f":"six_one"}}; 

具有相同的一组中的所有级别的?

例如deepCheckObjKeys(objOne, objTwo)将返回true其中deepCheckObjKeys(objOne, objThree)回报false,如果:

var objThree = {"a":"four","b":"five","c":{"g":"six_one"}}; 

由于objThree.a.c.fobjThreeundefined

类似这样的功能:

'use strict';

function objectsHaveSameKeys() { 
    for (var _len = arguments.length, objects = Array(_len), _key = 0; _key < _len; _key++) { 
     objects[_key] = arguments[_key]; 
    } 

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

只检查第一级。

PS:objectsHaveSameKeys()ES6相当于:

function objectsHaveSameKeys(...objects):boolean { 
    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); 
} 

回答

4

我只是做递归检查,如果属性的值是一个对象;看评论:

const deepSameKeys = (o1, o2) => { 
 
    // Get the keys of each object 
 
    const o1keys = Object.keys(o1).sort(); 
 
    const o2keys = Object.keys(o2).sort(); 
 
    // Make sure they match 
 
    // If you don't want a string check, you could do 
 
    // if (o1keys.length !== o2keys.length || !o1keys.every((key, index) => o2keys[index] === key)) { 
 
    if (o1keys.join() !== o2keys.join()) { 
 
    // This level doesn't have the same keys 
 
    return false; 
 
    } 
 
    // Check any objects 
 
    return o1keys.every(key => { 
 
    const v1 = o1[key]; 
 
    const v2 = o2[key]; 
 
    const t1 = typeof v1; 
 
    const t2 = typeof v2; 
 
    if (t1 !== t2) { 
 
     return false; 
 
    } 
 
    return t1 === "object" ? deepSameKeys(v1, v2) : true; 
 
    }); 
 
}; 
 
var objOne = {"a":"one","b":"two","c":{"f":"three_one"}}; 
 
var objTwo = {"a":"four","b":"five","c":{"f":"six_one"}}; 
 
var objThree = {"a":"four","b":"five","c":{"g":"six_one"}}; 
 

 
console.log("objOne, objTwo: " + deepSameKeys(objOne, objTwo)); 
 
console.log("objTwo, objThree: " + deepSameKeys(objTwo, objThree));

+0

尼斯。我可以问你为什么声明内部变量为const,而不是var? –

+0

@ThirueswaranRajagopalan:在ES2015及以上版本中,我默认为'const'。如果我需要在某个时候更改变量的值,则只使用'let',并且我不需要更改这些值。我根本不使用'var'。 (呃,除了我看到我在复制你的'objOne'上面的时候:-)) –

+0

Haaa,似乎是你的个人喜好:D Cool ... –

1

您可以创建递归函数将返回所有密钥,并检查它们是否与every()相等。

var objOne = {"a":"one","b":"two","c":{"f":"three_one"}}; 
 
var objTwo = {"a":"four","b":"five","c":{"f":"six_one"}}; 
 

 
function checkKeys(obj1, obj2) { 
 

 
    function inner(obj) { 
 
    var result = [] 
 

 
    function rec(obj, c) { 
 
     Object.keys(obj).forEach(function(e) { 
 
     if (typeof obj[e] == 'object') rec(obj[e], c + e) 
 
     result.push(c + e) 
 
     }) 
 
    } 
 
    rec(obj, '') 
 
    return result 
 
    } 
 

 
    var keys1 = inner(obj1), keys2 = inner(obj2) 
 
    return keys1.every(e => keys2.includes(e) && keys1.length == keys2.length) 
 
} 
 

 
console.log(checkKeys(objOne, objTwo))

相关问题