Is there a way to map on a map?

I know you can use enum.map but that returns a list and I’d like to return a map, with just different values than the original values.

I don’t know if this is the best method, but this works (pardon the function name):

def map_map(map, func) do
  map
  |> Enum.map(fn {key, value} -> {key, func.(value)} end)
  |> Enum.into(%{})
end

# map_map %{a: 2, b: 3}, &(&1 * &1)
# => %{a: 4, b: 9}
1 Like

It might be easier to use for comprehension
for {k, v} <- %{a: “y”, b: “n”}, into: %{}, do: {k, v <> v}

3 Likes

I believe that the for-comprehension is the better method here, as it will not create an intermediate list (the pipeline solution will).

Enum.map is not a true map because it is implemented on top of reduce (always turning the thing into a list.)

Oh, nice. I haven’t used for comprehension that much yet.

Everyone seems to forget that Map.new/2 exists as well.

foo |> Map.new(fn {key, value} -> {key, func.(value)} end)
6 Likes

At some point a long time ago, I think I remember seeing or asking for this… When was it added?