Reputation: 96827
I would have imagine that the following would work, based on articles I found online:
iex(9)> q
%{one: 1, two: 2}
iex(10)> nq = %{ q | three: 4}
** (KeyError) key :three not found in: %{one: 1, two: 2}
(stdlib) :maps.update(:three, 4, %{one: 1, two: 2})
(stdlib) erl_eval.erl:255: anonymous fn/2 in :erl_eval.expr/5
(stdlib) lists.erl:1262: :lists.foldl/3
iex(10)> nq = %{ q | :three => 4}
** (KeyError) key :three not found in: %{one: 1, two: 2}
(stdlib) :maps.update(:three, 4, %{one: 1, two: 2})
(stdlib) erl_eval.erl:255: anonymous fn/2 in :erl_eval.expr/5
(stdlib) lists.erl:1262: :lists.foldl/3
I was trying to add a new element to the map. Can anyone tell me what I'm doing wrong? I'm running the following:
Erlang/OTP 18 [erts-7.2] [source-e6dd627] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.3.0-dev) - press Ctrl+C to exit (type h() ENTER for help)
Upvotes: 3
Views: 1064
Reputation: 3607
Not what you're asking, but thought I'd post one way (which I guess is short enough) to expand on this to work with several Maps:
iex(1)> q = %{one: 1, two: 2}
%{one: 1, two: 2}
iex(2)> b = %{three: 3, four: 4}
%{four: 4, three: 3}
iex(3)> Enum.reduce([q, b, %{five: 5}], &Map.merge/2)
%{five: 5, four: 4, one: 1, three: 3, two: 2}
Upvotes: 1
Reputation: 4052
The |
is a map specific construct that provides the ability to update and access atom keys. Because their is no :three
key in %{one: 1, two: 2}
, it is throwing you an error.
What you need to use is Map.put/3
.
Example
iex(1)> q = %{one: 1, two: 2}
%{one: 1, two: 2}
iex(2)> q = Map.put(q, :three, 3)
%{one: 1, three: 3, two: 2}
Here, q
is rematched with the right hand side (iex(2)).
Further
Simon St. Laurent & J. David Eisenberg in their book Introducing Elixir: Getting Started In Functional Programming.
You may also want to add another key-value pair to a map. You can't of course, change the map intself, but the
Dict.put_new
library function can easily create a new map that includes the original plus an extra value:
iex(1)> q = %{one: 1, two: 2}
%{one: 1, two: 2}
iex(2)> Dict.put_new( q, :three, 3)
%{one: 1, three: 3, two: 2}
iex(3)> q = Dict.put_new( q, :three, 3)
However, even though it works this should be avoided as of Elixir 1.2 because Dict + HashDict has been deprecated. Just use the Map module functions.
Upvotes: 9