View Source MapWithIndifferentAccess (map_with_indifferent_access v1.0.0)
Utility functions making it easier to work with maps which can either have atom keys or string keys, but never both.
For example, you'll find it useful when working with Ecto.Changeset
,
as Ecto.Changeset.cast/4
forbids passing maps with mixed key types.
Nearly all functions mimic Map
interface, e.g. MapWithIndifferentAccess.put/3
works just as Map.put/3
, with two important differences:
You need to use atom keys when calling the functions. (Even if the map uses string keys.)
If the map uses string keys,
key
argument will be converted to a string, and only then called with a respectiveMap
function.
usage-example
Usage example
- Add
map_with_indifferent_access
to your list of dependencies inmix.exs
:
def deps do
[
{:map_with_indifferent_access, "~> 1.0.0"}
]
end
- Use
MapWithIndifferentAccess
instead ofMap
, where you are interacting with a map that can have either string or atom keys:
MapWithIndifferentAccess.get(%{a: 1}, :a) // # returns 1
MapWithIndifferentAccess.get(%{"a" => 1}, :a) // # returns 1
MapWithIndifferentAccess.put(%{a: 1}, :b, 2) // # returns %{a: 1, b: 2}
MapWithIndifferentAccess.put(%{"a" => 1}, :b, 2) // # returns %{"a" => 1, "b" => 2}
# Real world usage example
defmodule ProductController do
def create(conn, params) do
params
|> MapWithIndifferentAccess.put(:author_id, conn.assigns.current_user.id)
|> ProductService.create()
end
end
defmodule AdminController do
def create_test_product(conn, params) do
%{name: "test product"}
|> MapWithIndifferentAccess.put(:author_id, conn.assigns.current_user.id)
|> ProductService.create()
end
end
Link to this section Summary
Functions
Tries to deduce if the map uses string keys.
Link to this section Functions
Tries to deduce if the map uses string keys.
It does so by obtaining a random map key and verifying if it's a string.
Thus, if a map contains mixed key types (both strings and atoms), it may return either true and false, randomly. We don't take it as a problem, as this module is not meant to be used with such maps. (It should be used only with maps where all keys are strings or all keys are atoms.)