Iterating over a nested Map

Hi,

I’m new to Elixir and am trying to iterate over a nested map:

ex(52)> data
%{
  "Buy Milk" => %{
    "Date" => "23-Apr",
    "Notes" => "Make sure it's 2%",
    "Priority" => "4",
    "Urgency" => "3"
  },
  "Take out Trash" => %{
    "Date" => "20-Apr",
    "Notes" => "It's stinky!",
    "Priority" => "2",
    "Urgency" => "1"
  }
}

I’m able to extract the keys for the items:

iex(56)> Map.keys(data)
["Buy Milk", "Take out Trash"]

But I can’t plug them into data[x] to get the values for the nested item:

iex(57)> Enum.each(items, fn item -> IO.puts(data[item]) end)
** (Protocol.UndefinedError) protocol String.Chars not implemented for %{"Date" => "23-Apr", "Notes" => "Make sure it's 2%", "Priority" => "4", "Urgency" => "3"} of type Map
    (elixir 1.10.2) lib/string/chars.ex:3: String.Chars.impl_for!/1
    (elixir 1.10.2) lib/string/chars.ex:22: String.Chars.to_string/1
    (elixir 1.10.2) lib/io.ex:669: IO.puts/2
    (elixir 1.10.2) lib/enum.ex:783: Enum."-each/2-lists^foreach/1-0-"/2
    (elixir 1.10.2) lib/enum.ex:783: Enum.each/2

I think this is because it’s returning something like: data[key] instead of a string data[“key”]

Thank you,
Leo

If you’re just trying to find out what value you have, instead of IO.puts/1 you should use IO.inspect/1:

iex(57)> Enum.each(items, fn item -> IO.inspect(data[item]) end)

The error you’re getting

** (Protocol.UndefinedError) protocol String.Chars not implemented for %{"Date" => "23-Apr", "Notes" => "Make sure it's 2%", "Priority" => "4", "Urgency" => "3"} of type Map

Indicates that IO.puts doesn’t know how to handle the data it received.

3 Likes

Thank you! I was able to solve it with puts

Enum.each(items, fn item ->
      IO.puts( """
      Item: #{item}
        - Date: #{data[item]["Date"]}
        - Priority:  #{data[item]["Priority"]}
        - Urgency:  #{data[item]["Urgency"]}
        - Notes:  #{data[item]["Notes"]}
      - - - - - - - - - - - -
      """
    )end)