How to convert map keys from strings to atoms in Elixir

前端 未结 13 1188
梦毁少年i
梦毁少年i 2021-01-31 07:07

What is the way to convert %{\"foo\" => \"bar\"} to %{foo: \"bar\"} in Elixir?

13条回答
  •  孤街浪徒
    2021-01-31 07:40

    First of all, @Olshansk's answer worked like a charm for me. Thank you for that.

    Next, since the initial implementation provided by @Olshansk was lacking support for list of maps, below is my code snippet extending that.

      def keys_to_atoms(string_key_map) when is_map(string_key_map) do
        for {key, val} <- string_key_map, into: %{}, do: {String.to_atom(key), keys_to_atoms(val)}
      end
    
      def keys_to_atoms(string_key_list) when is_list(string_key_list) do
        string_key_list
        |> Enum.map(&keys_to_atoms/1)
      end
    
      def keys_to_atoms(value), do: value
    

    This the sample I used, followed by the output after passing it to the above function - keys_to_atoms(attrs)

    # Input
    %{
      "school" => "School of Athens",
      "students" => [
        %{
          "name" => "Plato",
          "subjects" => [%{"name" => "Politics"}, %{"name" => "Virtues"}]
        },
        %{
          "name" => "Aristotle",
          "subjects" => [%{"name" => "Virtues"}, %{"name" => "Metaphysics"}]
        }
      ]
    }
    
    # Output
    %{
      school: "School of Athens",
      students: [
        %{name: "Plato", subjects: [%{name: "Politics"}, %{name: "Virtues"}]},
        %{name: "Aristotle", subjects: [%{name: "Virtues"}, %{name: "Metaphysics"}]}
      ]
    }
    
    

    The explanation for this is very simple. The first method is the heart of everything which is invoked for the input of the type map. The for loop destructures the attributes in key-value pairs and returns the atom representation of the key. Next, while returning the value, there are three possibilities again.

    1. The value is yet another map.
    2. The value is a list of maps.
    3. The value is none of the above, it's primitive.

    So this time, when the keys_to_atoms method is invoked while assigning value, it may invoke one of the three methods based on the type of input. The methods are organized in the snippet in a similar order.

    Hope this helps. Cheers!

提交回复
热议问题