比较JavaScript中的2个JSON对象结构

fga*_*i03 5 javascript json

我正在将angular-translate用于大型应用程序。有几个人提交代码和翻译,很多时候翻译对象不同步。

我正在构建一个Grunt插件,以查看两个文件的结构并进行比较(只是键和整体结构,而不是值)。

主要目标是:

  • 查看每个文件,并检查整个对象(或本例中的文件)的结构是否与转换后的结构完全相同;
  • 错误时,返回不匹配的密钥。

事实证明,这比我预期的要复杂一些。所以我想我可以做类似的事情:

  1. 排序对象 ;
  2. 检查值包含的数据类型(由于它们是翻译,因此将仅包含字符串或嵌套对象)并将其存储在另一个对象中,使键等于原始键,并且值将是字符串'String ',如果是对象,则为对象。该对象包含子元素;
  3. 递归地重复步骤1-2,直到整个对象被映射并排序为止;
  4. 对所有文件执行相同的操作
  5. 整理并比较所有内容。

一个小例子是以下对象:

{
  key1: 'cool',
  key2: 'cooler',
  keyWhatever: {
    anotherObject: {
      key1: 'better',
      keyX: 'awesome'
    },
    aObject: 'actually, it\'s a string'
  },
  aKey: 'more awesomeness'
}
Run Code Online (Sandbox Code Playgroud)

将映射到:

{
  aKey: 'String',
  key1: 'String',
  key2: 'String',
  keyWhatever: {
    aObject: 'String',
    anotherObject: {
      key1: 'String',
      keyX: 'String'
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在此之后,我将对所有对象进行字符串化,并进行严格的比较。

我的问题是,有没有更好的方法来执行此操作?在简单性和性能方面,因为存在许多翻译文件,而且它们很大。

我试图寻找已经可以执行此操作的库,但找不到任何库。

谢谢

编辑谢谢贾里德指出无法排序的对象。我为这样的事情感到saying愧:D另一个解决方案可能是迭代主翻译文件上的每个属性,如果它们是字符串,则将键与其他文件进行比较。如果它们是对象,则“输入”它们,然后执行相同的操作。也许它比我的第一个猜测还要简单。应该做什么?

Jar*_*ith 4

假设您有两个 JSON 对象:jsonA 和 jsonB。

function compareValues(a, b) {

    //if a and b aren't the same type, they can't be equal
    if (typeof a !== typeof b) {
        return false;
    }
 
    // Need the truthy guard because
    // typeof null === 'object'
    if (a && typeof a === 'object') {
        var keysA = Object.keys(a).sort(),
            keysB = Object.keys(b).sort();

        //if a and b are objects with different no of keys, unequal
        if (keysA.length !== keysB.length) {
            return false;
        }

        //if keys aren't all the same, unequal
        if (!keysA.every(function(k, i) { return k === keysB[i];})) {
            return false;
        }

        //recurse on the values for each key
        return keysA.every(function(key) {
            //if we made it here, they have identical keys
            return compareValues(a[key], b[key]);
        });

    //for primitives just use a straight up check
    } else {
        return a === b;
    }
}

//true if their structure, values, and keys are identical    
var passed = compareValues(jsonA, jsonB); 
Run Code Online (Sandbox Code Playgroud)

请注意,对于深度嵌套的 JSON 对象,这可能会导致堆栈溢出。另请注意,这适用于 JSON,但不一定适用于常规 JS 对象,因为日期对象、正则表达式等需要特殊处理。