jasper sanchez
jasper sanchez

Reputation: 21

List of String to Map

I want to convert this set of list that I split from .txt file:

["a: 1", "b: 2", "c: 3"]

to:

%{"a" => "1", "b" => "2", "c" => "3"}

Upvotes: 1

Views: 219

Answers (3)

Daniel
Daniel

Reputation: 2554

The fastest way is to use the universal reduce/2:

list = ["a: 1", "b: 2", "c: 3"]
Enum.reduce(list, %{}, fn <<a::binary-size(1)>> <> ": " <> <<b::binary-size(1)>>, acc -> Map.put(acc, a, b) end)

Or another way would be to use into/2:

Enum.into(list, %{}, fn <<a::binary-size(1)>> <> ": " <> <<b::binary-size(1)>> -> {a, b} end)

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Just out of curiosity:

list = ["a: 1", "b: 2", "c: 3"]

<<?%, ?{, Enum.join(list, ",") :: binary, ?}>>
|> Code.eval_string()
|> elem(0)
#⇒ %{a: 1, b: 2, c: 3}

Please note that conversion to a map is doomed when the input has several values for the same key:

list = ["a: 1", "a: 2", "a: 3"]

<<?%, ?{, Enum.join(list, ",") :: binary, ?}>>
|> Code.eval_string()
|> elem(0)
#⇒ %{a: 3}

That’s why it’s better to convert the input to Keyword.

In general, one should probably modify the code that produces this weird input to return a Keyword instead in the first place.

Upvotes: -1

TheAnh
TheAnh

Reputation: 2813

for item <- ["a: 1", "b: 2", "c: 3"], into: %{} do
  [k, v] = String.split(item, ": ")
  {k, v}
end
# %{"a" => "1"}, %{"b" => "2"}, %{"c" => "3"}

Upvotes: 1

Related Questions