写在前面
本文主要是以一个erlang的学习记录,有错误的地方欢迎指正。
Snip20180615_22.png
映射 (Map)
映射组是键--值对的关联性集合。键可以是任意的Erlang数据类型。
键和值可以是任何有效的Erlang数据类型
注:map 要更新到最新的erl版本才能运行(R17版本的erlang 才添加map,所以致少要升到R17的版本)
%%Erlang R15B03 版本报错
➜ Cellar erl
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.3.1 (abort with ^G)
1> #{name =>"yzf" ,age=>26}.
* 1: syntax error before: '{'
1>
1>
%%Erlang/OTP 19 版本可以执行成功
[root@iz7mrdaho3jf9lz otp_src_19.1]# erl
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V8.1 (abort with ^G)
1> #{age => 26,name => "yzf"}.
#{age => 26,name => "yzf"}
创建映射组
Erlang 中的映射组用结构 #{} 表示
1> #{name => "youname", age=> 26}.
#{age => 26,name => "youname"}
%输出
2> #{}.
#{}
3>
更新映射组
% => 用于创建或更新一个映射
13> Me = #{name =>"zyf",age =>26}.
#{age => 26,name => "zyf"}
14> NewMe = Me#{age => 20}.
#{age => 20,name => "zyf"}
15> Me.
#{age => 26,name => "zyf"}
16>
16> #{name =>"zyf",age =>26}#{age =>27}.
#{age => 27,name => "zyf"}
17>
% 使用 :=,它只能用来更新映射,而不能创建新的映射,如果键不存在,就会抛出一个 badarg 异常
1> Me = #{name =>"zyf",age =>26}.
#{age => 26,name => "zyf"}
2> Me#{age := 27}.
#{age => 27,name => "zyf"}
3> Me#{aeg := 27}.
** exception error: {badkey,aeg}
in function maps:update/3
called as maps:update(aeg,27,#{age => 26,name => "zyf"})
in call from erl_eval:'-expr/5-fun-0-'/2 (erl_eval.erl, line 255)
in call from lists:foldl/3 (lists.erl, line 1263)
4>
将Map里的参数匹配出来
%部分匹配:
%只取出一个参数的映射
1> Me = #{age=> 19,name=>"zyfa"}.
#{age => 19,name => "zyfa"}
2> #{age := NewAge}=Me.
%重新匹配
#{age => 19,name => "zyfa"}
3> NewAge .
19
4>
4> #{age => NewAge2}=Me.
* 2: illegal pattern
%用=>符号去匹配会报错
5>
maps 模块
Erlang 中的 maps 模块用于操作映射组
映射组的创建及属性
%创建
6> maps:new().
#{}
%新建一个Me的映射
7> Me =#{age=>19,name=>"zyf"}.
#{age => 19,name => "zyf"}
%查询映射的所有键
8> maps:keys(Me).
[age,name]
9>
%判断是否存在键
%存在时
10> maps:is_key(age,Me).
true
%不存在时
11> maps:is_key(age111,Me).
false
%查询出Me里面的所有值
12> maps:values(Me).
[19,"zyf"]
%查询映射里面的数量
13> maps:size(Me).
2
% erlang:map_size/1 此函数可以用于 Guard,maps 模块内部也是使用此函数的
14> map_size(Me).
2
15>
映射的增加、删除、获取
% 获取映射里面的 age key 的值,找不到key时会报错
16> maps:get(age,Me).
19
% 查不到age123这个key的值,会报异常提示
17> maps:get(age123,Me).
** exception error: {badkey,age123}
in function maps:get/2
called as maps:get(age123,#{age => 19,name => "zyf"})
18>
% maps:get/3 在键不存在时会返回第三个参数的值
18> maps:get(age123,Me,18).
18
% 添加参数到映射里面,原映射组并不会改变
19> maps:put(gender,male,Me).
#{age => 19,gender => male,name => "zyf"}
20> Me.
#{age => 19,name => "zyf"}
% 用于更新映射,类似于 :=,键不存在时会抛出 badarg 异常
21>
21> maps:update(age,20,Me).
#{age => 20,name => "zyf"}
22> maps:update(age321,20,Me).
** exception error: {badkey,age321}
in function maps:update/3
called as maps:update(age321,20,#{age => 19,name => "zyf"})
23>
% 删除一个映射,键不存在时相当于什么都没做,不会抛出异常
23> maps:remove(age,Me).
#{name => "zyf"}
24>
% 查找键的值,键不存在时返回 error
24> maps:find(age,Me).
{ok,19}
25> Me.
#{age => 19,name => "zyf"}
26> maps:find(age3,Me).
error
27>
映射组的归并
% 新建一个Me映射
1> Me=#{age=> 10,name=>"zyfaa"}.
#{age => 10,name => "zyfaa"}
%新建一个Me1映射
2> Me2=#{height=>173}.
#{height => 173}
%将Me、Me2合并 height键会合并到新的映射里面
3> maps:merge(Me,Me2).
#{age => 10,height => 173,name => "zyfaa"}
%新建一个Me3映射,age为39
4> Me3=#{age=>39}.
#{age => 39}
%将Me、Me3合并 age会更新到最新的值
5> maps:merge(Me,Me3).
#{age => 39,name => "zyfaa"}
映射组与列表之间的转换
5> Me=#{age=> 10,name=>"zyfaa"}.
#{age => 10,name => "zyfaa"}
% 返回映射对应的列表
6> maps:to_list(Me).
[{age,10},{name,"zyfaa"}]
%从列表构建一个空的映射组
7> maps:from_list([]).
#{}
8>
%从列表构建一个新的映射组
9> maps:from_list([{name,"zfsfd"},{age,33}]).
#{age => 33,name => "zfsfd"}
10> Me21 = maps:from_list([{name,"zfsfd"},{age,33}]).
#{age => 33,name => "zfsfd"}
11>
映射组的遍历
% 对映射组的每对映射执行操作
% X, Y 分别为一对映射的键和值
11> Me21 = maps:from_list([{name,"zfsfd"},{age,33}]).
#{age => 33,name => "zfsfd"}
12> maps:map(fun (X, Y) -> io:format("~p => ~p~n",[X, Y]) end,Me21).
age => 33
name => "zfsfd"
#{age => ok,name => ok}
13>
% X, Y 分别为一对映射的键和值,V 为上一次迭代的结果,0 为迭代的初始值
% 这里简单的用于每次迭代时值加 1,结果就是映射组的映射数量
13> maps:fold(fun(X,Y,V) ->V + 1 end,0,Me).
2
映射组中映射的选取
1、返回第一个参数中指定的键的映射组成的映射组
14> maps:with([],Me).
#{}
15> maps:with([name],Me).
#{name => "zyfaa"}
16> maps:with([age],Me).
#{age => 10}
17>
17> maps:with([age22],Me).
#{}
2、返回键不再第一个参数的列表中的映射组成的映射组
18> maps:without([],Me).
#{age => 10,name => "zyfaa"}
19>
19> maps:without([age],Me).
#{name => "zyfaa"}
20> maps:without([age,name],Me).
#{}
% 键也可以不存在
21> maps:without([age,name234],Me).
#{name => "zyfaa"}
22>
注意
值得一提的是 maps 模块中的若干函数,比如 map, fold, with 和 without 都是使用 maps:to_list/1 转到列表,然后使用 lists 模块的工具处理,然后使用 maps:from_list/1 转回到映射组的。
引用网络博客内容:
https://blog.csdn.net/yangzm/article/details/50597409
https://www.w3cschool.cn/erlang/tohb1p5z.html (w3cschool erlang教程)
个人博客地址:https://zhangyongfeng1.github.io/
简书地址:https://www.jianshu.com/u/137f325832fb
网友评论