What is the way to convert %{\"foo\" => \"bar\"}
to %{foo: \"bar\"}
in Elixir?
I really liked Roman Bedichevskii's answer ... but I needed something that will thoroughly atomize the keys of deeply nested yaml files. This is what I came up with:
@doc """
Safe version, will only atomize to an existing key
"""
def atomize_keys(map) when is_map(map), do: Map.new(map, &atomize_keys/1)
def atomize_keys(list) when is_list(list), do: Enum.map(list, &atomize_keys/1)
def atomize_keys({key, val}) when is_binary(key),
do: atomize_keys({String.to_existing_atom(key), val})
def atomize_keys({key, val}), do: {key, atomize_keys(val)}
def atomize_keys(term), do: term
@doc """
Unsafe version, will atomize all string keys
"""
def unsafe_atomize_keys(map) when is_map(map), do: Map.new(map, &unsafe_atomize_keys/1)
def unsafe_atomize_keys(list) when is_list(list), do: Enum.map(list, &unsafe_atomize_keys/1)
def unsafe_atomize_keys({key, val}) when is_binary(key),
do: unsafe_atomize_keys({String.to_atom(key), val})
def unsafe_atomize_keys({key, val}), do: {key, unsafe_atomize_keys(val)}
def unsafe_atomize_keys(term), do: term
It's main limitation is that if you feed it a tuple {key, value} and the key is a binary, it will atomize it. That is something you want for keyword lists, but it is probably someone's edge case. In any case, YAML and JSON files don't have a concept of a tuple, so for processing those, it won't matter.