Reputation: 9008
Is it possible to make multiple case matching like in this example? I want to merge two maps, maps, can be like this:
map1 = %{"test" => [list]}
map2 = %{"test" => [list2]}
I can merge them like this if I know both v1 and v2 are lists:
Map.merge(map1, map2, fn _k, v1, v2 ->
do something with v1 and v2 knowing they are list
like Enum.concat(v1, v2)
end)
But it's possible to check v1 and v2 in a case clause?
Map.merge(map1, map2, fn _k, v1, v2 ->
case v1, v2 do
[v1] [v2] -> they are lists, do something with them
_ -> they are other thing
end
end)
Upvotes: 2
Views: 1391
Reputation: 1631
Your syntax is pretty close. Try giving your lambda multiple signatures, which syntactically looks very similar to a case:
defmodule TestMerge do
def merge(map1, map2) do
Map.merge(map1, map2, fn
_k, l1, l2 when is_list(l1) and is_list(l2) ->
#they are lists, do something with them
:lists
_, _, _ ->
#they are other thing
:not_lists
end)
end
end
To test, we call it with all four possibilities (the keys indicate which combination, e.g. both maps have a list after the :both
key, the first map has a list after the :first
key, but not the second map, etc.):
iex> TestMerge.merge(%{first: [], last: 1, both: [], neither: 1},
...> %{first: 2, last: [], both: [], neither: 1})
%{both: :lists, first: :not_lists, last: :not_lists, neither: :not_lists}
Upvotes: 2
Reputation: 3320
You could check the condition wether map1 and map2 are lists before you would do the merge:
result =
cond do
is_list(map1) && is_list(map2) -> Map.merge(...)
true -> :they_are_other_thing
end
If one of map1 and map2 is not a list the true condition will be used and result is :they_are_other_thing
in this example. Here are some cond examples.
Upvotes: 1