Skip to content

Instantly share code, notes, and snippets.

@jkone27
Last active August 22, 2023 19:26
Show Gist options
  • Save jkone27/5694c6a6575df274b3f8299606398c80 to your computer and use it in GitHub Desktop.
Save jkone27/5694c6a6575df274b3f8299606398c80 to your computer and use it in GitHub Desktop.
JsonDiffPath wrapper for case insensitivity and ignoring fields
using System;
using System.Collections.Generic;
using System.Linq;
using JsonDiffPatchDotNet;
using Newtonsoft.Json.Linq;
public static class JsonDiffPatchWrapper
{
private static readonly JsonDiffPatch JsonDiff = new JsonDiffPatch();
public static JToken DiffIgnoreProperties(Object oldResult, Object newResult,
params string[] ignoreProperties) =>
Diff(oldResult, newResult, ignoreProperties, Array.Empty<string>());
public static JToken DiffIgnoreCasingInValuesForProperties(Object oldResult, Object newResult,
params string[] ignoreCasingForProperties) =>
Diff(oldResult, newResult, Array.Empty<string>(), ignoreCasingForProperties);
public static JToken Diff(Object oldResult, Object newResult,
string[] ignoreProperties = null,
string[] ignoreCasingForProperties = null)
{
if (newResult is null && oldResult is null)
{
return null;
}
if (newResult is null)
{
return JToken.FromObject(oldResult);
}
if (oldResult is null)
{
return JToken.FromObject(newResult);
}
var diff = JsonDiff.Diff(JToken.FromObject(oldResult), JToken.FromObject(newResult));
foreach (var property in ignoreProperties ?? Array.Empty<string>())
{
var selected = diff.SelectTokens($"..{property}");
var parentObj = selected.FirstOrDefault().Parent.Parent as JObject;
selected.ToList().ForEach(t => t.Parent.Remove()); // remove properties
if (parentObj is not null && !parentObj.Properties().Any())
{
parentObj.Parent.Remove(); // remove property of parent
}
}
foreach (var uncasedProp in ignoreCasingForProperties ?? Array.Empty<string>())
{
var selected = diff.SelectTokens($"..{uncasedProp}");
var uniquePropertyValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var prop in selected)
{
var firstChildren = prop.Children().First().Children().FirstOrDefault();
if (firstChildren is not null)
{
foreach (var v in firstChildren.Values<string>())
{
uniquePropertyValues.Add(v);
}
}
}
if (uniquePropertyValues.Count <= 1)
{
selected.ToList().ForEach(t => t.Parent.Remove()); // remove properties
}
}
if (diff?.FirstOrDefault() is null)
{
return null;
}
return diff;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment