I have come across wanting to do this a couple of times in the past as well.
But before that, I do want to mention that there are two related situations that have more elegant solutions: 1) You want to create a map or structure where fields that were not supplied (e.g. by the user request) fall back to a default. This can be done with patterns like this: query = %MyRequest{ language: params["language"] || "english", id: params["id"] || session.id } 2) You want to pick one of a restricted set of choices; also known as working with a 'sum type': shape = case params["shape"] do "square" -> %Square{position: params["position"], width: params["width"], height: params["height"]} "circle" -> %Circle{position: params["position"], radius: params["radius"]} _ -> raise ArgumentError, "unknown kind of shape provided" end If you are able to use either of these approaches in a specific use-case, then you can reduce the number of input checks you need to do later on. (In your original example code, all functions operating on `query` will have to check again if `:language` and/or `:id` exist.) Having said that, there definitely are cases where you want to normalize a map with string keys to a map with recognized atom keys (to ensure that (a) you dont exhaust memory by creating more and more atoms and (b) reject inputs that you cannot handle). The pattern I have used in the past was similar to: def normalize_keys(into \\ %{}, input, accepted_keys) do string_keys = MapSet.new(accepted_keys, &to_string/1) Enum.reduce(input, into, fn {string_key, val}, acc -> if string_key in string_keys do put_in(acc, [:"#{string_key}"], val) else acc end end) end And use it as: iex> normalize_keys(%{"language" => "english", "id" => 33, "disregard_me" => 10}, [:id, :language]) %{id: 33, language: "english"} Do note that this has a slightly different result from your original code, since `string_key in string_keys` checks for the existance of a key, while `params[string_key]` checks for the existance of a key AND the value stored under key being truthy. Only after writing out this code I realize its similarity to Ecto.Changeset.cast/4 <https://hexdocs.pm/ecto/Ecto.Changeset.html#cast/4> which seems to deal with a variant of the same problem. A common pattern for sure, interesting. ~Marten / Qqwy -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/d307d598-a012-4b41-9700-c31f8fc07faa%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.