Augustin Riedinger
Augustin Riedinger

Reputation: 22198

Elixir map_values in a map?

Ain't there a standard lib function that would allow to execute a map_values function over a map:

Map.map_values(%{a: 30, b: 45}, fn v -> v*2 end) # = %{a: 60, b: 90}

The best way I found is:

Enum.map(%{a: 30, b: 45}, fn {k, v} -> {k, map_fn(v)}) |> Enum.into(%{})

which I find pretty heavy since I use this quite often...

Upvotes: 2

Views: 210

Answers (3)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

While the already given answers are perfectly correct, for the sake of exhaustiveness I’d post another variant: there is Enum.into/3 that also might be used because Map implements Collectable protocol.

Enum.into(%{a: 30, b: 45}, %{}, fn {k, v} -> {k, v * 2} end)
#⇒ %{a: 60, b: 90}

Upvotes: 4

Adam Millerchip
Adam Millerchip

Reputation: 23101

I don't think so, but you can do it more concisely with Map.new/2:

iex> Map.new(%{a: 30, b: 45}, fn {k, v} -> {k, v * 2} end)
%{a: 60, b: 90}

Upvotes: 5

Tano
Tano

Reputation: 1377

An alternative to this is a for comprehension e.g

a = %{a: 30, b: 45}
    for {k, v} <- a, into: %{} do
      {k, v + 1}
    end

output :

%{a: 31, b: 46}

Through this way you are not creating an intermediate list, because Enum.map return a list and then you need to convert it to map. Here the important part is the into: %{} because if you omit it, it will return you a list by default.

Upvotes: 4

Related Questions