Skip to content

Instantly share code, notes, and snippets.

@schinsue
Forked from boydm/map_difference.ex
Created September 27, 2017 08:23
Show Gist options
  • Save schinsue/c27b1e1da09bcd9e7a188f8a134c7ea0 to your computer and use it in GitHub Desktop.
Save schinsue/c27b1e1da09bcd9e7a188f8a134c7ea0 to your computer and use it in GitHub Desktop.
Elixir meyers_difference for Maps
defmodule Boydm.Utilities.Map do
#============================================================================
# similar to List.meyers_difference, the below code compares two maps
# and generates a list of actions that can be applied to the first map
# to transform it into the second map.
#--------------------------------------------------------
def difference(map_1, map_2) when is_map(map_1) and is_map(map_2) do
# remove any keys from map_1 that are simply not present (at all) in map_2
difference = Enum.reduce(map_1, [], fn({k,_}, d)->
case Map.has_key?(map_2, k) do
false -> [{:del, k} | d]
true -> d
end
end)
# add any puts for keys that have changed between map_2 to map_1
Enum.reduce(map_2, difference, fn({k,v}, d)->
case Map.has_key?(map_1, k) && (Map.get(map_1, k) == v) do
false -> [{:put, k, v} | d]
true -> d
end
end)
end
#--------------------------------------------------------
def apply_difference(map, difference) when is_map(map) and is_list(difference) do
Enum.reduce(difference, map, fn(diff, acc)->
case diff do
{:put, k, v} -> Map.put(acc, k, v)
{:del, k} -> Map.delete(acc, k)
end
end)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment