【问题标题】:Difference in JSON objects using Javascript/JQuery使用 Javascript/JQuery 的 JSON 对象的差异
【发布时间】:2010-11-15 02:14:34
【问题描述】:

我在 Javascript 中有两个 JSON 对象,除了数值之外是相同的。它看起来像这样:

var data = {
  "eth0":{"Tx":"4136675","Rx":"13232319"},
  "eth1":{"Tx":"4","Rx":"0"},
  "lo":{"Tx":"471290","Rx":"471290"}
}

var old = {
  "eth0":{"Tx":"4136575","Rx":"13232219"},
  "eth1":{"Tx":"4","Rx":"0"},
  "lo":{"Tx":"471290","Rx":"471290"}
}

一个名为“data”的对象具有当前值,另一个名为“old”的对象具有与 1 秒前相同的值。我想输出一个只有 change 值的 JSON 对象,这样我就可以计算网络接口上的数据吞吐量。

var throughput = {
  "eth0":{"Tx":"100","Rx":"100"},
  "eth1":{"Tx":"0","Rx":"0"},
  "lo":{"Tx":"0","Rx":"0"}
}

我不确定如何遍历 JSON 数据 - 它可能适用于任意数量的接口。

谁能帮帮我?提前致谢

【问题讨论】:

标签: javascript jquery json


【解决方案1】:

这是使用object-scan 的解决方案。还没有测试过,但是这个解决方案应该很快,因为我们跟踪了两个参考

// const objectScan = require('object-scan');

const data = { eth0: { Tx: '4136675', Rx: '13232319' }, eth1: { Tx: '4', Rx: '0' }, lo: { Tx: '471290', Rx: '471290' } };

const old = { eth0: { Tx: '4136575', Rx: '13232219' }, eth1: { Tx: '4', Rx: '0' }, lo: { Tx: '471290', Rx: '471290' } };

const computeThroughput = (dataOld, dataNew) => objectScan(['**'], {
  breakFn: ({ property, value, context: { stack, result } }) => {
    if (property === undefined) {
      return;
    }

    const stackRef = stack[stack.length - 1][property];
    stack.push(stackRef);

    const resultRefParent = result[result.length - 1];
    if (!(property in resultRefParent)) {
      if (typeof stackRef === 'string') {
        resultRefParent[property] = String(Number.parseFloat(stackRef) - Number.parseFloat(value));
      } else {
        resultRefParent[property] = {};
      }
    }
    const resultRef = resultRefParent[property];
    result.push(resultRef);
  },
  filterFn: ({ context: { stack, result } }) => {
    stack.pop();
    result.pop();
  }
})(dataOld, {
  stack: [dataNew],
  result: [{}]
}).result[0];

console.log(computeThroughput(old, data));
/* => {
  lo: { Rx: '0', Tx: '0' },
  eth1: { Rx: '0', Tx: '0' },
  eth0: { Rx: '100', Tx: '100' }
} */
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

免责声明:我是object-scan的作者

【讨论】:

    【解决方案2】:

    在处理类似问题时,这对我很有帮助。与第一个相比,它得到第二个的差异。

    var first  = originalObj;
    var second = modifiedObj;
    var diff   = {};
    
    var differ = function(first, second, result) {
        var i = 0;
        for (i in first) {
            if (typeof first[i] == "object" && typeof second[i] == "object") {
                result[i] = differ(first[i], second[i], {});
                if (!result[i]) delete result[i];
            } else if (first[i] != second[i]) {
                result[i] = second[i];
            }
        }
        return isEmpty(result) ? undefined : result;
    }
    
    differ(old_conf, new_conf, diff);
    

    代码有点特殊,但你明白了一般的想法:P

    【讨论】:

      【解决方案3】:

      您可以使用像nervgh/object-traverse 这样的对象遍历模块来执行此操作。

      var result = {}
      Object.traverse(old, function(node, value, key, path) {
        var resultObject = result
        for(var n=0; n<path.length-1; n++) {
          resultObject = resultObject[path[n]]
        }
        resultObject[key] = value
      });
      

      【讨论】:

        【解决方案4】:

        也许它已经回答得够多了,但让我添加我的无耻插件:) 我在 github 上开源的一个 JSON(实际上是任何 javascript 对象或数组结构)差异和补丁库:

        https://github.com/benjamine/jsondiffpatch

        它生成差异(也是 JSON 格式,占用空间小),您可以使用客户端(检查测试页面)和服务器端,如果存在,它会自动使用 http://code.google.com/p/google-diff-match-patch/ 处理长字符串。

        查看DEMO 页面以了解其工作原理。

        【讨论】:

        • +1 复杂的 json diff 算法,例如使用字符串属性,决定是使用完整的 beforeafter 字符串还是对字符串进行差异 inside,具体取决于字符串的长度产生的差异(我假设)。
        • 是的,当找到 2 个长(可配置多长时间)字符串时,会完成文本差异(为了减小差异大小,并允许模糊修补)。
        【解决方案5】:

        您可以遍历父对象和子对象属性:

        var diff = {};
        for(var p in data){
          if (old.hasOwnProperty(p) && typeof(data[p]) == 'object'){
            diff[p] = {};
            for(var i in data[p]){
              if (old[p].hasOwnProperty(i)){
                diff[p][i] = data[p][i] - old[p][i];
              }
            }
          }
        }
        

        【讨论】:

          【解决方案6】:

          在 JavaScript 中迭代对象的基本前提是这样的

          var whatever = {}; // object to iterate over
          for ( var i in whatever )
          {
            if ( whatever.hasOwnProperty( i ) )
            {
               // i is the property/key name
               // whatever[i] is the value at that property
            }
          }
          

          修复检查器不会太难。你需要递归。我会把它留给你或其他 SOer 作为练习。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-06-16
            • 2012-01-15
            • 1970-01-01
            • 2015-11-22
            • 1970-01-01
            • 1970-01-01
            • 2023-03-26
            相关资源
            最近更新 更多