Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dict.merge is deprecated, what's the simplest way to merge a Keyword List with a Map?

Tags:

elixir

The Dict module was soft deprecated starting in Elixir v1.2. We're now at 1.4 and it raises warnings:

Dict.merge/2 is deprecated, use the Map module for working with maps or the Keyword module for working with keyword lists

Dict.merge used to work like this:

iex(1)> animals_keyword_list = [cats: 2, dogs: 1]
[cats: 2, dogs: 1]
iex(2)> animals_map = %{cats: 3, rabbits: 1}
%{cats: 3, rabbits: 1}
iex(3)> Dict.merge(animals_map, animals_keyword_list)
%{cats: 2, dogs: 1, rabbits: 1}

What's the best way to handle a simple keyword list -> map merge going forward?

like image 320
Darian Moody Avatar asked Jan 14 '17 13:01

Darian Moody


2 Answers

Both Map and Keyword implement the Enumerable and Collectable protocols, so we can use Enum.into/2:

iex(4)> animals_keyword_list |> Enum.into(animals_map)
%{cats: 2, dogs: 1, rabbits: 1}

Note, this solution requires you to be happy that if there are duplicate keys in the keyword list, the last one declared will overrule any previous ones as Maps cannot have duplicate keys. You can see this when you instead do the reverse and merge the Map into the Keyword List, which can support duplicate keys:

iex(5)> animals_map |> Enum.into(animals_keyword_list)
[cats: 2, dogs: 1, cats: 3, rabbits: 1]
like image 177
Darian Moody Avatar answered Sep 22 '22 17:09

Darian Moody


Instead of Dict.merge/2 you should simply use Map.merge/2.

map1 = %{name: "bob"}
map2 = %{name: "fred", wife: "wilma"}
Map.merge(map1, map2) # %{name: "fred", wife: "wilma"}

The same rule for keyword lists and using Keyword.merge/2.

In your example I would use Map.merge/2 with Enum.into for keyword list.

Map.merge(animal_map, Enum.into(animal_keyword_list, %{}))

or only using Map module:

Map.merge(animal_map, Map.new(animal_keyword_list))
like image 22
PatNowak Avatar answered Sep 19 '22 17:09

PatNowak