这个elixir地图示例有什么问题?

时间:2016-01-15 18:06:45

标签: elixir

根据我在网上找到的文章,我会想象以下内容可行:

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

我试图在地图上添加一个新元素。 谁能告诉我我做错了什么?我正在运行以下内容:

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)

2 个答案:

答案 0 :(得分:9)

|是一个特定于地图的构造,可以更新和访问原子键。因为:three中的密钥不是%{one: 1, two: 2},所以它会给您一个错误。

您需要使用的是Map.put/3

示例

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}

此处,q与右侧(iex(2))重新匹配。

另外

Simon St. Laurent& J. David Eisenberg在他们的书“介绍Elixir:功能编程入门”一书中。

  

您可能还想为地图添加另一个键值对。你不能   当然,改变地图自己,但Dict.put_new库   功能可以轻松创建包含原始加号的新地图   额外价值:

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)

然而,即使它起作用,也应该避免使用Elixir 1.2,因为Dict + HashDict has been deprecated。只需使用Map模块功能。

答案 1 :(得分:1)

不是你要问的问题,但我认为我发布了一种方式(我认为这个方法足够短)可以扩展这个方式来处理几个地图:

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}