2009-07-29 14 views
15

Tengo dos objetos JSON en Javascript, idénticos excepto por los valores numéricos. Se ve así:Diferencia en objetos JSON usando Javascript/JQuery

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

Un objeto llamado "datos" tiene los valores actuales, otro objeto llamado "viejo" tiene los mismos valores de hace 1 segundo. Me gustaría generar un objeto JSON con el change en valores para que pueda calcular el rendimiento de datos en las interfaces de red.

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

no estoy seguro de cómo hacer para atravesar los datos JSON - que podría ser para cualquier número de interfaces.

¿Alguien puede ayudarme por favor? Gracias de antemano

+0

Una buena respuesta también encontrar aquí: [? ¿Cómo se puede mapear las diferencias entre los objetos de JavaScript] (http://codereview.stackexchange.com/questions/11412/how-can-you-map-the- differences-between-javascript-objects/11580 # 11580) – laggingreflex

+0

para la comparación del lado del cliente, tal vez http://tlrobinson.net/projects/javascript-fun/jsondiff/ puede ser útil. – Veverke

Respuesta

7

Se puede recorrer las propiedades de los padres y de objetos secundarios:

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]; 
     } 
    } 
    } 
} 
14

La premisa básica para iterar sobre los objetos en JavaScript es como tan

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

fijación de un corrector no sería demasiado duro. Necesitarás recursividad. Lo dejaré como un ejercicio para ti u otro SOer.

4

Esto hizo el truco para mí cuando se trata de un problema similar. Obtiene las diferencias en segundo lugar en comparación con el primero.

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

Código es un poco de un caso especial, pero usted consigue la idea general: P

8

Tal vez ya ha sido respondida suficiente, pero permítanme añadir mi enchufe descarado :) Un JSON (en realidad cualquier javascript objeto o la matriz de estructura) diff & biblioteca de parches I de código abierto en github:

https://github.com/benjamine/jsondiffpatch

genera diffs (también en formato JSON, y con una pequeña huella), que se puede utilizar cl (verifique la página de prueba) & del lado del servidor, y si está presente, usa http://code.google.com/p/google-diff-match-patch/ para cadenas largas automáticamente.

consulta la página DEMO para ver cómo funciona.

+0

+1 Un sofisticado algoritmo json diff, p. Ej. con los atributos de cadena, la decisión de utilizar el * antes * completo y * después de * cadena o hacer un diff ** dentro ** de la cadena, dependiendo de la duración del diff resultante (supongo). –

+0

Sí, una diferencia de texto se realiza cuando se encuentran 2 cadenas largas (por cuánto tiempo es configurable) (para reducir el tamaño del diff y también para permitir parches borrosos). – Benja

0

Puede usar un módulo transversal de objetos como nervgh/object-traverse para hacerlo.

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