Open Cyber1000 opened 1 year ago
Seems like I can use following JsonDiffOptions to control array-comparison:
Looks promising, the following works as expected (I've changed bar1 to ID since this would be my real-world example, if for any reason the ID is missing I'm falling back with ArrayObjectItemMatchByPosition=true):
var node1 = JsonNode.Parse("{\"foo\":[ {\"ID\": \"res1\", \"bar2\": \"res3\"} ]}");
var node2 = JsonNode.Parse("{\"foo\":[ {\"ID\": \"res1\", \"bar2\": \"res4\"} ]}");
var opt = new JsonDiffOptions
{
ArrayObjectItemKeyFinder = ArrayObjectItemKeyFinder,
ArrayObjectItemMatchByPosition = true
};
object? ArrayObjectItemKeyFinder(JsonNode? node, int index)
{
if (node is JsonObject obj && obj.TryGetPropertyValue("ID", out var value))
{
return value?.GetValue<string>() ?? "";
}
return null;
}
var x = JsonDiffPatcher.Diff(node1, node2, new JsonPatchDeltaFormatter(), opt);
Console.WriteLine(x);
Did I miss out any documentation about this?
Yes works this way:
What's the best method to check arrays recursively (the way I want)?
I think you've pretty much found the way.
If you have a look at the JsonDiffOptions
, there are 3 ways you can use:
ArrayItemMatcher
which deals with the diff contextArrayObjectItemKeyFinder
which finds the key/id of an object or arrayArrayObjectItemMatchByPosition
which indicates whether to compare two objects or arrays by their positionBy default if the two objects are not deeply equal to each other, then they are considered totally not equal and therefore the remove/add
(arguably update) result. To forcibly get a diff of array items, you need to implement an "object comparer" to compare them if they are not deeply equal, similar to an object hash function.
There probably should be some Wiki documentation about array diffs.
JsonPatchDeltaFormatter.PropertyPathScope should be protected instead of private
I agree. The reason for it being a private is because the implementation of the class is actually a combination of partial JSON Pointer and a pointer scope at the moment. The JSON Pointer implementation should ideally be a public type. I did not want to expose this type until it is properly refactored otherwise it might be hard to change the implementation.
With the following code (excluded the usings for simplicity)
I'm getting follwing:
I would like to get something like:
I've looked into DefaultFormatter and it seems that JsonDiffDelta has already 2 change entries: one for remove and one for add.
What's the best method to check arrays recursively (the way I want)? Is there some kind of flag or would I need to override FormatArray somehow?
Thanks!