48

Possible Duplicate:
Object comparison in JavaScript

Is there any method that takes in 2 JSON objects and compares the 2 to see if any data has changed?

Edit

After reviewing the comments, some clarification is needed.

  1. A JSON object is defined as

    "an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma)." -- json.org

  2. My goal is to be able to compare 2 JSON object literals, simply put.

I am not a javascript guru so if, in javascript, these are object literals, then I suppose that's what I should call them.

I believe what I am looking for is a method capable of:

  1. Deep recursion to find a unique name/value pair
  2. Determine the length of both object literals, and compare the name/value pairs to see if a discrepancy exists in either.
Community
  • 1
  • 1
  • 2
    There is nothing like a JSON object. Either JSON string or JavaScript object, but not a combination of either of these (ok, maybe JavaScript string exists ;)). – Felix Kling Dec 16 '10 at 21:50
  • @mjw06d Are you wanting to compare to strings that happen to be JSON for objects, or are you wanting to compare two existing JavaScript `Object` instances? – Phrogz Dec 16 '10 at 23:09
  • 4
    @Felix Kling, you're right but conversationally a "JSON object" to me means what in Java is called a POJO... a plain object containing only (a hierarchy of) primitives, as opposed to an Object with a constructor, private or public functions etc... Not technically correct, but it helps in understanding the question. – David Tang Dec 16 '10 at 23:35
  • @box9 I appreciate your input. However, the term "JSON object" is incorrect. If we can get @mjw06d to clarify his intent, this question is either a direct duplicate of existing questions, or should be retitled to something like "Compare 2 JSON object strings". – Phrogz Dec 16 '10 at 23:51
  • 1
    @Felix Kling, *Phrogz: In JSON terminology, an object is the kind of entity that is delimited by braces. So, yes there is such a thing as a JSON object. (section 2.2 of the RFC http://www.ietf.org/rfc/rfc4627.txt?number=4627 ) – JeremyP Dec 17 '10 at 10:50
  • @JeremyP: Ok, then lets say **in JSON** there are JSON objects, JSON arrays, etc. but **in JavaScript**, there are only strings containing JSON. The problem is when talking about JSON and JavaScript at the same time, one cannot be sure, in situations like this, whether the other person really knows what he is talking about or there is some misconception. This is also interesting: http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/ – Felix Kling Dec 17 '10 at 11:02
  • @Felix, That's a good article worth looking through. I think I've clarified my request a bit so hopefully it's more helpful to the community. –  Dec 17 '10 at 13:57
  • @mjw06d: The question is whether you have `var x = '{"a": 1}';` (JSON string with an object) or `var x = {a: 1}` (JavaScript object literal). From your edit assume the latter one. – Felix Kling Dec 17 '10 at 14:25
  • @Felix, yes it's an object literal, although such technicality can be easily overcome by serializing/deserializing it. I'm mainly just interested in how to compare them. –  Dec 17 '10 at 14:42
  • @mjw06d: It cannot always be serialized. E.g. not if the object contains functions as properties. But if you are talking about object literals, then your question was already answered. – Felix Kling Dec 17 '10 at 14:59
  • You can use https://github.com/mirek/node-rus-diff to check for differences, `rusDiff(a, b)` returns `false` if `a` and `b` are the same. – Mirek Rusin Mar 11 '14 at 17:28
  • If you want to view the changes from json doc a to doc b check out rfc 6902 for json patch and its implementations.. E.g. A Java one here https://github.com/flipkart-incubator/zjsonpatch – Mark D Apr 18 '15 at 08:29
  • You could use a package that helps you do this like: https://www.npmjs.com/package/js-object-compare – SomeDutchGuy Oct 31 '19 at 14:55

1 Answers1

13

Simply parsing the JSON and comparing the two objects is not enough because it wouldn't be the exact same object references (but might be the same values).

You need to do a deep equals.

From http://threebit.net/mail-archive/rails-spinoffs/msg06156.html - which seems the use jQuery.

Object.extend(Object, {
   deepEquals: function(o1, o2) {
     var k1 = Object.keys(o1).sort();
     var k2 = Object.keys(o2).sort();
     if (k1.length != k2.length) return false;
     return k1.zip(k2, function(keyPair) {
       if(typeof o1[keyPair[0]] == typeof o2[keyPair[1]] == "object"){
         return deepEquals(o1[keyPair[0]], o2[keyPair[1]])
       } else {
         return o1[keyPair[0]] == o2[keyPair[1]];
       }
     }).all();
   }
});

Usage:

var anObj = JSON.parse(jsonString1);
var anotherObj= JSON.parse(jsonString2);

if (Object.deepEquals(anObj, anotherObj))
   ...
jd.
  • 4,057
  • 7
  • 37
  • 45