Code golf on Map.merge/put

Is there any nicer way to write the following? Not that it’s terrible to write, I just wonder if there’s a more concise style. It always feels kind of clunky and rote spreading it out over 4 lines every time.

case Map.has_key?(map, key) do
  true -> Map.merge(map, %{key => value + map[key]})
  false -> Map.put(map, key, value)
end

I know I can do %{map | key => value} if the key already exists but it doesn’t help me if they key is missing.

I thought I could do

Map.merge(map, %{key => value}, &(&2 + &3))

but you can’t reference capture &2 without &1 (why is this by the way? I guess some optimisation?).

Is

Map.merge(map, %{key => value}, fn (_, v1, v2) -> v1 + v2 end)

the best one liner?

Can you elaborate what the difference between the two clauses is supposed to be? Map.merge(map, %{key => value}) will produce exactly the same result as Map.put(map, key, value).

Map.update(map, key, value, & value + &1)

Or do I get you wrong here?

4 Likes

Ah I misread the docs on update, I thought it was saying it only called the function if the new value matches the old. I think it’s probably exactly what I want.

No, it calls the update fun if the key already has a value and passes in the old value.