While performing a code review, I started to reflect on how to get a specific key in an Elixir map while specifying a default fallback value.
I really like the Map.get/3
approach:
data = %{foo: "bar"}
Map.get(data, :foo, "default")
# => "bar"
Map.get(data, :foo2, "default")
# => "default"
And I was wondering why would someone use the Access
behaviour + ||
operator approach for the same purpose:
data = %{foo: "bar"}
data[:foo] || "default"
# => "bar"
data[:foo2] || "default"
# => "default"
The end result is the same, right? Not quite! If we start messing around with the nil
value for an existing key, the result will differ!
data = %{foo: "bar", baz: nil}
data[:baz] || "default"
# => "default"
Map.get(data, :baz, "default")
# => nil 😱
Map.get/3
only falls back to the default value (the third argument) if the key doesn’t exist in the map while ||
will fallback to the second expression if the first expression does not evaluate to a truthy value (nil
is not truthy).
So there you have it, use Map.get/3
wisely: when you’re sure you’re using fallback default values when the key doesn’t exist, not just as a simple fallback for non-truthy values.
✌