Skip to content

Instantly share code, notes, and snippets.

@sescobb27
Last active December 24, 2019 13:12
Show Gist options
  • Save sescobb27/e4714471ecccae28084118ad20c189f9 to your computer and use it in GitHub Desktop.
Save sescobb27/e4714471ecccae28084118ad20c189f9 to your computer and use it in GitHub Desktop.
defmodule MergeCommonPlaces do
def merge_places([]), do: []
def merge_places([place | rest]) do
{similar_places, rest_places} =
Enum.reduce(rest, {[], []}, fn plc, {same_places, rest} ->
if same_place?(place, plc) do
{[plc | same_places], rest}
else
{same_places, [plc | rest]}
end
end)
merged_place = Enum.reduce(similar_places, place, fn pplace, place_acc ->
merge_both_places(place_acc, pplace)
end)
[merged_place | merge_places(rest_places)]
end
defp same_place?(place1, place2) do
String.jaro_distance(place1.name, place2.name) >= 0.9
end
defp merge_both_places(place1, place2) do
Map.merge(place1, place2, fn
:source, _, _ -> "aggregated_source"
# pick always the existing name
:name, value1, _value2 -> value1
# merge lists
_key, value1, value2 when is_list(value1) and is_list(value2) ->
Enum.concat(value1, value2)
# pick a non-empty string
_key, value1, value2 when is_binary(value1) and is_binary(value2) ->
if value1 == "", do: value2, else: value1
# else don't override
_key, value1, _value2 -> value1
end)
end
end
places = [%{name: "Domino's", img: ['1']}, %{name: "Pepe", img: ['2']}, %{name: "Unique", img: ['3']}, %{name: "Pepe", img: ['4']}, %{name: "Dominos", img: ['5']}]
IO.inspect(MergeCommonPlaces.merge_places(places)) # [%{img: ['1', '5'], name: "Domino's"}, %{img: ['2', '4'], name: "Pepe"}, %{img: ['3'], name: "Unique"}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment