Determining equality of JSON formatted objects in node.js
Friends! I am very sorry if I do not understand something or if I explain the question in incorrect expressions. All I want to do is compare the equality of two pieces of standardized JSON data:
{"skip":0, "limit":7, "arr": [1682, 439, {"x":2, arr:[]}] }
{"skip":0, "limit":7, "arr": [1682, 450, "a", ["something"] }
I am 100% sure that there will be no functions in this data Date
, null
or undefined
, etc. My point is that I don't want to compare JavaScript objects in the most general case (with complex prototypes, circular references, and all that). The prototype for this data will be Object
. I am also sure that many skilled programmers have answered this question in front of me.
The main thing I'm missing is that I don't know how to properly explain my question. Please feel free to edit my post.
My answer:
The first way: Ineffective, but reliable. You can change the general method like this so you don't waste time looking for functions and undefined
. Note that the generic method iterates the objects three times (three inside them for .. in
)
Method two: Effective, but has one limitation. I found JSON.stringify
very quickly in node.js . Fastest solution that works:
JSON.stringify(data1) == JSON.stringify(data2)
Very important to note! As far as I know, neither JavaScript nor JSON has any meaning to the field order of an object. However, if you compare strings from objects, it makes a big difference. In my program, the object fields are always created in the same order, so the code above works. I didn't look in the V8 documentation, but I think we can rely on the order in which the fields are created. Otherwise, be aware of using this method.
In my particular case, the second method is 10 times more efficient than the first.
source to share
At first glance, I believe this is what you are looking for:
Comparing objects in JavaScript
However, a more complete answer can be found here:
How do you determine equality for two JavaScript objects?
These answers are from 2 and 3 years ago, respectively. It is always advised to search the site for a given question before submitting, or to search Google more broadly - "javascript compares two JSON objects" on Google returns a lot. Top 4 hits are all StackOverflow answers.
source to share
You can use rename / unset / set diff for JSON objects - https://github.com/mirek/node-rus-diff
npm install rus-diff
Your example JSON Objects:
a = {"skip":0, "limit":7, "arr": [1682, 439, {"x":2, arr:[]}] }
b = {"skip":0, "limit":7, "arr": [1682, 450, "a", ["something"]] }
var rusDiff = require('rus-diff').rusDiff
console.log(rusDiff(a, b))
... let's generate the following diff:
{ '$set': { 'arr.1': 450, 'arr.2': 'a', 'arr.3': [ 'something' ] } }
... which is MongoDB compatible diff format.
rusDiff(a, b)
Returns if the documents are the same false
.
source to share
I went through several steps of various methods, with the underscore coming out from the top:
> node nodeCompare.js
deep comparison res: true took: 418 (underscore)
hash comparison res: true took: 933
assert compare res: true took: 2025
string compare res: true took: 1679
Here is the source code:
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()));
source to share