map-with-indifferent-access
map-with-indifferent-access copied to clipboard
MapWithIndifferentAccess
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,
keyargument will be converted to a string, and only then called with a respectiveMapfunction.
Usage
-
Add
map_with_indifferent_accessto your list of dependencies inmix.exs:def deps do [ {:map_with_indifferent_access, "~> 1.0.0"} ] end -
Whenever you are interacting with a map that can have either string or atom keys, instead of using
Map.*functions such asMap.getorMap.put, useMapWithIndifferentAccess.*functions (e.g.MapWithIndifferentAccess.getMapWithIndifferentAccess.put.When referring to map keys, specify them as atoms (instead of strings).
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, %{"name" => _name} = 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
Documentation
See Hex docs.
Contributing
Running tests
Run the following after cloning the repo:
mix deps.get
mix test