I have been writing a lot of elixir and one thing that keeps cropping my code is when I want to update the value of a map only if the key already exists, I end up with code like this:
def incSomething(state, key) do
{_, state} = get_and_update_in(state.way.down.there[key], fn
nil -> :pop
j -> {nil, j + 1}
end)
state
end
Sometimes there's a lot of code involved and sometimes there are nested get_and_update_ins so it gets messy.
I initially found myself wanting to use the update_in/2
macro, but it seems to function as more of an upsert than an update rather like the difference between update
and replace into
in sql.
Map.update/4
allows you to set a default, but doesn't allow you to not set anything. Map.update!/3
outright errors if the key is missing.
Is there a less awkward way to do this in the standard language? Or do I have to write my own?
You can use Map.replace/3
to do exactly that - update the value of a key, only if that key exists in the map.
This function is available only since Elixir 1.5, for previous versions you'll need to implement it yourself. Fortunately, it's rather easy.
def update_existing(map, key, value) do
case map do
%{^key => _} -> %{map | key => value}
%{} -> map
end
end
Alternatively, if you want to use the function-style update you could modify it slightly:
def update_existing(map, key, fun) do
case map do
%{^key => old} -> %{map | key => fun.(old)}
%{} -> map
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With