2016-01-15 30 views
3

我会想象下面会工作的基础上,文章我在网上找到:这个仙丹地图的例子有什么问题?

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) 
+0

我猜我一直在寻找为'Map.put/3'。有没有更简单的方法,就像一些特殊的操作员一样? – Geo

+0

对不起,我现在只看到这个,并没有在我的答案中解决这个问题!我认为没有,如果是的话,我从来没有遇到过。 –

回答

9

|是地图特定的结构,提供了能力更新和存取原子键。因为%{one: 1, two: 2}中没有:three键,所以会给你一个错误。

你需要使用的是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))。

而且

西蒙·圣·洛朗& J.大卫·艾森伯格在他们的书中介绍药剂:入门函数式编程。

您可能还想要将另一个键值对添加到地图。你不能 当然,改变地图intself,但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。只需使用地图模块功能即可。

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}