Эликсир map_values ​​на карте? - PullRequest
1 голос
/ 09 апреля 2019

Разве нет стандартной функции lib, которая позволяла бы выполнять функцию map_values над map:

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

Лучший способ, который я нашел:

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

, который я нахожу довольно тяжелым, поскольку я использую это довольно часто ...

Ответы [ 3 ]

4 голосов
/ 09 апреля 2019

Я так не думаю, но вы можете сделать это более кратко с Map.new/2:

iex> Map.new(%{a: 30, b: 45}, fn {k, v} -> {k, v * 2} end)
%{a: 60, b: 90}
3 голосов
/ 12 апреля 2019

Хотя уже приведенные ответы совершенно верны, для полноты картины я выложу еще один вариант: есть Enum.into/3, который также может быть использован , поскольку Map реализует Collectable протокол.

Enum.into(%{a: 30, b: 45}, %{}, fn {k, v} -> {k, v * 2} end)
#⇒ %{a: 60, b: 90}
3 голосов
/ 09 апреля 2019

Альтернативой этому является для понимания например

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

вывод:

%{a: 31, b: 46}

Таким образом, вы не создаете промежуточный список, потому что Enum.map возвращает список, а затем вам нужно преобразовать его в карту. Здесь важной частью является into: %{}, потому что, если вы его опустите, он вернет вам список по умолчанию.

...