代码之家  ›  专栏  ›  技术社区  ›  Al.

使用Javascript/JQuery时JSON对象的差异

  •  15
  • Al.  · 技术社区  · 17 年前

    我在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秒前的相同值。我想输出一个JSON对象,其中只包含 输入值,以便计算网络接口上的数据吞吐量。

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

    我不知道如何遍历JSON数据——它可以用于任何数量的接口。

    5 回复  |  直到 17 年前
        1
  •  14
  •   Peter Bailey    17 年前

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

    修好一个格子不会太难。你需要递归。我把它留给你或其他人做练习。

        2
  •  8
  •   Benja    12 年前

    也许答案已经足够了,但让我加上我的无耻插头:) JSON(实际上是任何javascript对象或数组结构)差异&修补程序库I在github开源:

    https://github.com/benjamine/jsondiffpatch

    它生成diff(也是JSON格式,占用空间小),您可以使用客户端(检查测试页面)&服务器端,如果存在,则使用 http://code.google.com/p/google-diff-match-patch/

    检查 DEMO 页面查看它是如何工作的。

        3
  •  7
  •   dev.e.loper    13 年前

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

    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];
          }
        }
      }
    }
    
        4
  •  4
  •   wjandrea sebs    7 年前

    在处理类似问题时,这对我起到了作用。它得到秒与第一秒的差异。

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

        5
  •  0
  •   B T    11 年前

    您可以使用对象遍历模块,如 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
    });
    
        6
  •  0
  •   vincent    5 年前

    下面是一个使用 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