Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir: Convert a list into a map with integer keys

How do you go from a list: ~w[dog cat sheep]

to a map with integer keys: %{1=> "dog", 2=> "cat", 3=> "sheep"}

My Attempt:

iex(1)> list = ~w[dog cat sheep]
["dog", "cat", "sheep"]
iex(2)> list |> Enum.with_index|>Enum.map(fn({a,b})->{b+1,a} end)|> Enum.into %{}

%{1=> "dog", 2=> "cat", 3=> "sheep"}

Is there a simpler way?

like image 671
Charles Okwuagwu Avatar asked Feb 07 '26 10:02

Charles Okwuagwu


1 Answers

Here's a one-liner version:

for {v, k} <- ~w[dog cat sheep] |> Enum.with_index, into: %{}, do: {k+1, v}

And here's the same thing as a reusable function in a module:

defmodule Example do
  def to_indexed_map(list, offset \\ 0)
      when is_list(list)
      and is_integer(offset),
    do: for {v, k} <- list |> Enum.with_index,
      into: %{},
      do: {k+offset, v}
end

Example usage:

iex> list = ~w[dog cat sheep]
["dog", "cat", "sheep"]
iex> Example.to_indexed_map(list)
%{0 => "dog", 1 => "cat", 2 => "sheep"}

Minor Update: A less concise, but more performant version (roughly 2x faster) is shown below.

defmodule Example do
  def to_indexed_map(list, offset \\ 0)
      when is_list(list)
      and is_integer(offset),
    do: to_indexed_map(list, offset, [])

  defp to_indexed_map([], _k, acc),
    do: :maps.from_list(acc)
  defp to_indexed_map([v | vs], k, acc),
    do: to_indexed_map(vs, k+1, [{k, v} | acc])
end
like image 71
potatosalad Avatar answered Feb 09 '26 10:02

potatosalad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!