javascriptnode.jsjsoncomparediff

JavaScript compare two JSON files and outputting new objects only


I want to compare two JSON files and output only the newly added objects based on their "Id". I also need to ignore changes in the position of the objects within the JSON file (I don't want to compare line changes).

You'll notice in the code below that Greg's age has changed - I don't want to include these sort of (Key:Value) changes in my output either.

I'm currently using a package called json-diff.

Here's my current code:

const jsonDiff = require('json-diff');

var oldJson = {
    "data": [ 
      {
        "Id": "2",
        "Name": "Greg",
        "ranges": [
          {
            "age": "70"
          }
        ]
      },
      {
        "Id": "1",
        "Name": "Tom",
        "ranges": [
          {
            "age": "10"
          }
        ]
      }
    ]
};

var newJson = {
    "data": [
      {
        "Id": "2",
        "Name": "Greg",
        "ranges": [
          {
            "age": "20" // Even though Greg's age has changed, I don't want it in my output
          }
        ]
      },
      {
        "Id": "3",
        "Name": "Bob",
        "ranges": [
          {
            "age": "30"
          }
        ]
      },  
      {
        "Id": "1",
        "Name": "Tom",
        "ranges": [
          {
            "age": "10"
          }
        ]
      }
    ]
};

function compare(newJson, oldJson) {
    let rawDiff = jsonDiff.diff(newJson.data, oldJson.data);
    let prettyDiff = JSON.stringify(rawDiff).replace(/,\[" "]/g, '');
    console.log(prettyDiff);
}

compare(newJson, oldJson);

Current output:

[
  [
    "~",
    {
      "ranges": [
        [
          "-",
          {
            "age": "20"
          }
        ],
        [
          "+",
          {
            "age": "70"
          }
        ]
      ]
    }
  ],
  [
    "-",
    {
      "Id": "3",
      "Name": "Bob",
      "ranges": [
        {
          "age": "30"
        }
      ]
    }
  ]
]

Required output:

{
    "data": [
      {
        "Id": "3",
        "Name": "Bob",
        "ranges": [
          {
            "age": "30"
          }
        ]
      }
    ]
}

Solution

  • i'm not sure if this is your need but

    var oldJson = {
        "data": [ 
          { "Id": "2", "Name": "Greg", "ranges": [ { "age": "70" } ] },
          { "Id": "1", "Name": "Tom", "ranges": [ { "age": "10" } ] }
        ]
    };
    
    var newJson = {
        "data": [
            { "Id": "2", "Name": "Greg", "ranges": [ { "age": "20" } ] },
            { "Id": "3", "Name": "Bob", "ranges": [ { "age": "30" } ] },  
            { "Id": "1", "Name": "Tom", "ranges": [ { "age": "10" } ] }
        ]
    };
    
    function compare(newJson, oldJson) {
        // get Id's from oldJson
        let ids = oldJson.data.map(ch => ch.Id);
        // filter from newJson that's not inside from old ids
        return newJson.data.filter(ch => !ids.includes(ch.Id));
    }
    
    console.log(compare(newJson, oldJson)); // [ { Id: '3', Name: 'Bob', ranges: [ [Object] ] } ]