# How to convert map keys atoms to string?

I have a map like this

``````%{
day: [:*],
extended: false,
hour: [:*],
minute: [{:/, :*, 21}],
month: [:*],
reboot: false,
second: [:*],
weekday: [:*],
year: [:*]
}
``````

When I’m trying to convert this by this method

Enum.reduce(%{}, fn ({key, val}, acc) → Map.put(acc, String.to_atom(key), val) end)

It’s giving me this

``````** (ArgumentError) errors were found at the given arguments:

* 1st argument: not a binary

:erlang.binary_to_atom(:day, :utf8)
(stdlib 3.15.2) erl_eval.erl:685: :erl_eval.do_apply/6
(stdlib 3.15.2) erl_eval.erl:790: :erl_eval.eval_map_fields/5
(stdlib 3.15.2) erl_eval.erl:251: :erl_eval.expr/5
(stdlib 3.15.2) maps.erl:410: :maps.fold_1/3
``````

and how do I solve this problem efficiently ?

1 Like

You don’t need a reduce in that case because You transform a map, You do not reduce it…

``````map = %{
day: [:*],
extended: false,
hour: [:*],
minute: [{:/, :*, 21}],
month: [:*],
reboot: false,
second: [:*],
weekday: [:*],
year: [:*]
}
Map.new map, fn {k, v} -> {to_string(k), v} end
``````

And it’s to_string when You want to convert atoms to string.

6 Likes

As @kokolegorille said this is a perfect use for `Map.new/2`.

Just in case you want to fix your code with `Enum.reduce/3`,

1. it’s fine to use `reduce` because under the scene, `Map.new/2` is built on top of `Enum.map/2` which uses `Enum.reduce/3` (in this case of Map).

2. you can change your code into something like this:

``````map = %{foo: "bar"}

Enum.reduce(map, %{}, fn {key, value}, acc ->
Map.put(acc, to_string(key), value)
end)
``````

ps. You can use a comprehension too:

``````for {k, v} <- map, into: %{}, do: {to_string(k), v}
``````
5 Likes