public static JObject FindDiff(this JToken Current, JToken Model)
{
var diff = new JObject();
if (JToken.DeepEquals(Current, Model)) return diff;
switch(Current.Type)
{
case JTokenType.Object:
{
var current = Current as JObject;
var model = Model as JObject;
var addedKeys = current.Properties().Select(c => c.Name).Except(model.Properties().Select(c => c.Name));
var removedKeys = model.Properties().Select(c => c.Name).Except(current.Properties().Select(c => c.Name));
var unchangedKeys = current.Properties().Where(c => JToken.DeepEquals(c.Value, Model[c.Name])).Select(c => c.Name);
foreach (var k in addedKeys)
{
diff[k] = new JObject
{
["+"] = Current[k]
};
}
foreach (var k in removedKeys)
{
diff[k] = new JObject
{
["-"] = Model[k]
};
}
var potentiallyModifiedKeys = current.Properties().Select(c => c.Name).Except(addedKeys).Except(unchangedKeys);
foreach (var k in potentiallyModifiedKeys)
{
var foundDiff = FindDiff(current[k], model[k]);
if(foundDiff.HasValues) diff[k] = foundDiff;
}
}
break;
case JTokenType.Array:
{
var current = Current as JArray;
var model = Model as JArray;
var plus = new JArray(current.Except(model, new JTokenEqualityComparer()));
var minus = new JArray(model.Except(current, new JTokenEqualityComparer()));
if (plus.HasValues) diff["+"] = plus;
if (minus.HasValues) diff["-"] = minus;
}
break;
default:
diff["+"] = Current;
diff["-"] = Model;
break;
}
return diff;
}
public static JObject FindDiff(this 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);
foreach(var tag in ModifiedTags)
{
var foundDifference = Compare(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 = Compare(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;
}