8
votes

Détermination de l'égalité des objets formatés JSON dans Node.js

Quel est le moyen le plus efficace de comparer deux données d'objets formatés JSON dans Node.js?

Ces objets ne contiennent pas de "indéfini" ou de fonctions et leur propotype est objet .

J'ai entendu dire qu'il y a un bon soutien si JSON dans NODE.JS


5 commentaires

Qu'est-ce que "un json?" Quel genre de comparaison?


JSON est un objet qui se compose de chaînes, de chiffres, de booléens, de dates, de tableaux et d'autres jsons. tableau peut également contenir des jsons


@Dan: mal; C'est un objet . JSON est un format.


Je vois; Vous voulez dire des pojos (anciens objets javascript simples)


Je suggère json.stringify (x) === json.stringify (y)


4 Réponses :



7
votes

amis! Je suis vraiment désolé si je ne comprends pas quelque chose ou d'expliquer la question en mauvais termes. Tout ce que je veux faire, c'est comparer l'égalité de deux morceaux de données json-standardisés tels que ceci:

{"Skip": 0, "Limite": 7, "Ar": [1682, 439, {"X": 2, Arr: []}]}

{"Skip": 0, "Limite": 7, "ARRI": [1682, 450, "A", ["quelque chose"]}

Je suis sûr que je suis sûr qu'il n'y aura pas de fonctions, date , null ou non défini , etc. dans ces données. Je veux dire que je ne veux pas comparer des objets JavaScript dans le cas le plus général (avec des prototypes complexes, des liaisons circulaires et tout ce genre de choses). Le prototype de ces données sera objet . Je suis également sûr que beaucoup de programmeurs habiles ont répondu à cette question devant moi.

La principale chose qui me manque, c'est que je ne sais pas comment expliquer ma question correctement. S'il vous plaît n'hésitez pas à modifier mon message.

ma réponse:

première méthode: sans éléments mais fiables. Vous pouvez modifier une méthode générique comme celle-ci afin qu'il ne perd pas de temps à chercher des fonctions et indéfini . Veuillez noter que la méthode générique iTère les objets trois fois (il y a trois pour .. dans boucles à l'intérieur)

Deuxième moyen: efficace mais a une restriction. J'ai trouvé json.stringify est extrêmement rapide dans nœud.js . La solution la plus rapide qui fonctionne est la suivante:

json.stringify (data1) == json.stringify (Data2)

Note très importante! Autant que je sache, ni JavaScript ni Json ne comptent pas l'ordre des champs d'objets. Cependant, si vous comparez des cordes faites d'objets, cela importera beaucoup. Dans mon programme, les champs d'objet sont toujours créés dans le même ordre, de sorte que le code ci-dessus fonctionne. Je n'ai pas cherché dans la documentation V8, mais je pense que nous pouvons compter sur l'ordre de création de champs. Dans d'autres cas, soyez au courant de l'utilisation de cette méthode.

Dans mon cas concret, la deuxième façon est 10 fois plus efficace que la première façon.


2 commentaires

Mais est la deuxième manière fiable? J'ai entendu dire que cette méthode est controversée car JavaScript ne conserve pas l'ordre des propriétés et votre solution dépend de cela.


@juzerali. Vous avez tout à fait raison, je devrais modifier ma réponse en fonction de cette question



1
votes

Vous pouvez utiliser Rename / nonset / Set Diff pour les objets JSON - https://github.com / mirek / nœud-rus-diff xxx pré>

Votre exemple d'exemple JSON Objets: P>

{ '$set': { 'arr.1': 450, 'arr.2': 'a', 'arr.3': [ 'something' ] } }


0 commentaires

4
votes

J'ai fait de l'analyse comparative des différentes techniques, avec un soulignement de soulignement sur le dessus:

var _ = require('underscore');

var assert = require('assert');

var crypto = require('crypto');

var large = require('./large.json');

var large2 = JSON.parse(JSON.stringify(large));

var t1 = new Date();
var hash = crypto.createHash('md5').update(JSON.stringify(large)).digest('hex');
var t2 = new Date();

var res = _.isEqual(large, large2);

var t3 = new Date();

var res2 = (hash == crypto.createHash('md5').update(JSON.stringify(large2)).digest('hex'));

var t4 = new Date();

assert.deepEqual(large, large2);

var t5 = new Date();

var res4 = JSON.stringify(large) === JSON.stringify(large2);

var t6 = new Date();

console.log("deep comparison res: "+res+" took: "+ (t3.getTime() - t2.getTime()));
console.log("hash comparison res: "+res2+" took: "+ (t4.getTime() - t3.getTime()));
console.log("assert compare  res: true took: "+ (t5.getTime() - t4.getTime()));
console.log("string compare  res: "+res4+" took: "+ (t6.getTime() - t5.getTime()));


1 commentaires

Votre hachage et votre chaîne se comparent (parfois?) Renvoyer false (non égale) pour {A: 1, B: 1} et {b: 1, A: 1} Objets JSON, d'autres méthodes reviendront (toujours) true (égale).