corka149 / jsonpatch

A implementation of RFC 6902 in pure Elixir.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

diff/2 is not returning the added map, instead its returning the key

webdeb opened this issue · comments

Jsonpatch.diff(%{"a" => []}, %{"a" => [%{"b" => 1}]})
-> [{"op" => "add", "path" => "a/0/b", "value" => 1 }]

Expected:

-> [{"op" => "add", "path" => "a/0", "value" => %{"b" => 1}]

Thanks for your feedback. I will do some research on this.

This would be great. I must admit, that I've given up on finding a quick fix

Jsonpatch checks currently if that one specific path is missing. It never checks if the siblings of path are also missing. I would formulate this as the question: Is there any descendant path under a/0 in the target?

Yeah, I also thought about somewhat like this, but traversing the tree backwards to check which ancestor exists on the destination seemed to impact performance badly. I think that instead of creating the flat_map it would be enough to use Map.to_list and dive into the source structure recursively and create only the required operations in a single reduce loop.

Because you will have situations like %{a: []}, %{a: [%{b: [%{z: [4, %{a: %{a: "abc"}}]}], c: %{a: "a"}}]}

The second map will produce a lot of flat key:value pairs which are just a waste of time, as only one operation is required here. but its also not that simple because you also have to deal with other ops not just adds.

You are right. I also were suspicious about the performance, but more about memory consumption. My first thought here was to add the ancestor also to the flat_map. My hope was that the speed of accessing values by key in a map would be superior enough. I am not sure today why I not implemented as you described it. The advantages are obviously. Hence, Jsonpatch.diff/2 will be re-implemented with reduce.

@webdeb Would you like to review my PR? I would be very proud if you could so. :-)