View Source KeyDiff (KeyDiff v0.1.0)
Provides a single function, diff/3
for comparing two maps.
Lists
List diff is not implemented, and lists are treated like any single value of a key.
If any key value is a list and the list contents change, then this is reflected in the updates
list
of the return tuple as a path to the key. The contents of the items in the list are not diffed.
In order to work around this limitation, it is advised to turn lists into mapped representations - especially where the items in the list are maps that can be uniquely identified by one of their keys.
For example:
a = %{"key_a" => [%{"id": 1}, %{"id": 2}, %{"id": 3}]}
should first be transformed into the following map:
a = %{"key_a" => %{1 => %{"id": 1}, 2 => %{"id": 2}, 3 => %{"id": 3}}}
This way, a
can now be used with diff/3
and it will look for changes in the maps under the "key_a"
key value.
Summary
Functions
Compares two maps/structs and returns a tuple of lists containing differences between the two maps.
Types
@type key() :: term()
Functions
@spec diff(a :: map(), b :: map(), options :: keyword()) :: {additions :: [key_path()], deletions :: [key_path()], updates :: [key_path()]}
Compares two maps/structs and returns a tuple of lists containing differences between the two maps.
The returning result is a tuple containing 3 lists:
list of additions - a list of keys new in the map list of deletions - a list of keys removed from the previous map list of updates - list of keys that had their values modified
Options
depth
(default:nil
), an integer that will stop the diffing at the specified level of depth in the map; it will recurse into the map onlydepth
number of times. If not set ornil
then it will process the entire map tree.
This is useful in quickly determining changes in depth
number of levels, instead of having the entire
structure processed.
Examples
# No differences between the two maps
iex> KeyDiff.diff(%{a: 1}, %{a: 1})
{[], [], []}
# Top-level key is changed.
iex> KeyDiff.diff(%{a: 1}, %{a: 2})
{[], [], [:a]}
# Top level key `:a` is removed and key `:b` is added
iex> KeyDiff.diff(%{a: 1}, %{b: 2})
{[:b], [:a], []}
# Second level key `:b` is removed and second level key `:c` is modified
# `[:a, [:b]]` represents the top-level key `:a` under which keys `[:b]` are removed
# from.
# `[:a, [:c]]` represent the top-level key `:a` under which keys `[:c]` are changed.
iex> KeyDiff.diff(%{a: %{b: "b", c: "c"}}, %{a: %{c: "d"}})
{[], [[:a, [:b]]], [[:a, [:c]]]}