2017-01-23 108 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))

相關問題