9mm
Elixir way to conditionally update a map
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a loss how to do this without an if statement. I also don’t know if rebinding the same variable is a ‘code smell’
data = %{
requireInteraction: true,
title: title,
icon: icon,
click_action: click_action
}
if body do
data = Map.put(data, :body, body)
end
Most Liked
gregvaughn
I’ve written a helper function for this sort of thing before
def maybe_put(map, _key, nil), do: map
def maybe_put(map, key, value), do: Map.put(map, key, value)
Then you can use for multiple fields and pipe easily, for example:
data = %{
requireInteraction: true,
title: title,
icon: icon,
click_action: click_action
}
|> maybe_put(:body, body)
|> maybe_put(:other_field, other_value)
Eiji
I don’t like to have two variables with same name in scope. For me such code is less readable.
If you have only one variable like that then use if or && with || instead like:
data = %{…}
updated_data = if body, do: Map.put(data, :body, body), else: data
# or
updated_data = body && Map.put(data, :body, body) || data
In case you need to do it multiple times then I recommend to do something like:
data = %{…}
data2 = %{example: 5, body: body, sample: 10}
Enum.reduce(data2, data, fn {key, value}, acc -> value && Map.put(acc, key, value) || acc)
This is equivalent for maps:
:maps.filter(fn _key, value -> not is_nil(value) end, data)
peerreynders
Statement mindset:
Expression mindset:
Statements don’t work in an expression based language - that’s why.








