Skip to content

Instantly share code, notes, and snippets.

@tkouba
Created February 16, 2023 17:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkouba/1323296a538bf53ac064a5f5096533c2 to your computer and use it in GitHub Desktop.
Save tkouba/1323296a538bf53ac064a5f5096533c2 to your computer and use it in GitHub Desktop.
Compare two JSON and find the difference
/// <summary>
/// Compare two JSON and create diff object
/// </summary>
/// <param name="leftJson">Left JSON to compare</param>
/// <param name="rightJson">Right JSON to compare</param>
/// <returns>Diff object with the result.</returns>
/// <remarks>
/// Original version https://stackoverflow.com/a/65222961/1498252 by Rohith Daruri
/// based on https://stackoverflow.com/a/53654737/1498252 by Dzmitry Paliakou
/// </remarks>
public static JObject FindDiff(JToken leftJson, JToken rightJson)
{
var difference = new JObject();
if (JToken.DeepEquals(leftJson, rightJson)) return difference;
switch (leftJson.Type)
{
case JTokenType.Object:
{
var LeftJSON = leftJson as JObject;
var RightJSON = rightJson as JObject;
var RemovedTags = LeftJSON.Properties().Select(c => c.Name).Except(RightJSON.Properties().Select(c => c.Name));
var AddedTags = RightJSON.Properties().Select(c => c.Name).Except(LeftJSON.Properties().Select(c => c.Name));
var UnchangedTags = LeftJSON.Properties().Where(c => JToken.DeepEquals(c.Value, RightJSON[c.Name])).Select(c => c.Name);
foreach (var tag in RemovedTags)
{
difference[tag] = new JObject
{
["-"] = LeftJSON[tag]
};
}
foreach (var tag in AddedTags)
{
difference[tag] = new JObject
{
["+"] = RightJSON[tag]
};
}
var ModifiedTags = LeftJSON.Properties().Select(c => c.Name).Except(AddedTags).Except(UnchangedTags).Except(RemovedTags);
foreach (var tag in ModifiedTags)
{
var foundDifference = FindDiff(LeftJSON[tag], RightJSON[tag]);
if (foundDifference.HasValues)
{
difference[tag] = foundDifference;
}
}
}
break;
case JTokenType.Array:
{
var LeftArray = leftJson as JArray;
var RightArray = rightJson as JArray;
if (LeftArray != null && RightArray != null)
{
if (LeftArray.Count() == RightArray.Count())
{
for (int index = 0; index < LeftArray.Count(); index++)
{
var foundDifference = FindDiff(LeftArray[index], RightArray[index]);
if (foundDifference.HasValues)
{
difference[$"{index}"] = foundDifference;
}
}
}
else
{
var left = new JArray(LeftArray.Except(RightArray, new JTokenEqualityComparer()));
var right = new JArray(RightArray.Except(LeftArray, new JTokenEqualityComparer()));
if (left.HasValues)
{
difference["-"] = left;
}
if (right.HasValues)
{
difference["+"] = right;
}
}
}
}
break;
default:
difference["-"] = leftJson;
difference["+"] = rightJson;
break;
}
return difference;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment