erlang 中 maps 练习

there are more tricks over here
相关资料:
当我们谈论Erlang Maps时,我们谈论什么 Part 1
Erlang 的新数据结构 map 浅析 - siyao

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Maps Module Maps Syntax
maps:new/1 #{}
maps:put/3 Map#{Key => Val}
maps:update/3 Map#{Key := Val}
maps:get/2 Map#{Key}
maps:find/2 #{Key := Val} = Map
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
基本成员函数:
new() -> Map
find(Key, Map) -> {ok, Value} | error
我当时在windows 上面测试的是一个异常,我不想处理, 我去,原来就是一个原子 error,坑死了
get(Key, Map) -> Value
get(Key, Map, Default) -> Value | Default 这个在我的Eshell 6.0还是不能用
is_key(Key, Map) -> boolean()
keys(Map) -> Keys
put(Key, Value, Map1) -> Map2
remove(Key, Map1) -> Map2
size(Map) -> integer() >= 0
update(Key, Value, Map1) -> Map2
values(Map) -> Values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
带有函数的使用:
fold(Fun, Init, Map) -> Acc
from_list(List) -> Map
from_list(List) -> Map
map(Fun, Map1) -> Map2
merge(Map1, Map2) -> Map3
to_list(Map) -> [{Key, Value}]
with(Ks, Map1) -> Map2 当前都还是没有测试成功过的
without(Ks, Map1) -> Map2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
我不能理解的就是这个了 erlang文档中有 maps:get/3这个函数的,但是在这时不能用
maps:get(key3, #{}, "Default value").
** exception error: undefined function maps:get/3

exception exit: undef
in function maps:with/2
called as maps:with([1,2,"Good"],#{"Good" => rain,"lovely" => smile})

shankyan@early:~/ShankYan/erlang$ erl
Erlang/OTP 17 [erts-6.0] [source] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

maps:get/3 说是没定义,我想是因为我是 EShell 6.0 的原因吧? 用 EShell 6.1 直接就可以了,但是还不确定原因
Erlang/OTP 17 [erts-6.1] [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:false]
Eshell V6.1 (abort with ^G)
1> maps:get(a, #{},b).
b

还有就是put 的 操作,直接函数变量可以用,但是用符号 变量就会报错

26> Key = "Key".
"Key"
27> Map = #{Key =>a}.
'* 1: illegal use of variable 'Key' in map
28> maps:put(Key, a, #{}).
'#{"Key" => a}

我认为的是 => 只能在初始化的时候使用
可是测试后,是可以用的呀

Erlang/OTP 17 [erts-6.1] [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:false]

Eshell V6.1 (abort with ^G)
1> maps:get(a, #{},b).
b
3> MapA = #{a =>b}.
'#{a => b}
4> MapA#{c =>d}.
'#{a => b,c => d}

关于 with 成员函数

with(Ks, Map1) -> Map2
Types:
Ks = [K]
Map1 = Map2 = #{}
K = term()
Returns a new map Map2 with the keys K1 through Kn and their associated values from map Map1. Any key in Ks that does not exist in Map1 are ignored.
Example:

Map = #{42 => value_three,1337 => "value two","a" => 1},
Ks = ["a",42,"other key"],
maps:without(Ks,Map).
'#{42 => value_three,"a" => 1}
文档上都没有举例 with 函数,
在 6.1 中也没有with
2> maps:with([1, 2, "Good"], #{a =>b}).
** exception error: undefined function maps:with/2
3>

maps 使用例子:

(1)FunctionMap = maps:new(),
(2)Putfunctionmap = maps:put(Key, Value, FunctionMap),
(3)try maps:get(Key, FunctionMap) of
GotValue ->
io:format("get ~p => pn", [Key, GotValue])
catch
%%will fail with an exception,
error:Error ->
io:format("get Error: pn", [Error])
end,
case maps:find(Key, FunctionMap) of
{ok, FoundValue} ->
io:format("find ~p => ~p is in FunctionMap ~n", [Key, FoundValue]);
error ->
io:format("find ~p not exits in FunctionMap~n", [Key]);
_ ->
io:format("impossible return for maps:findnn")
end,
(4)try maps:get(genious, FunctionMap, you_are_not_genious) of
GeniousValue ->
io:format("get genious the result is pn", [GeniousValue])
catch
%%undef is error
error:Error ->
io:format("when use maps:get/3 Get Error, The error is pn", [Error])
end,
(5)maps:is_key(great, FunctionMap)
maps:keys(FunctionMap)
maps:put("lovely", smile, FunctionMap)
maps:update("Good", rain, PutFunctionMaps)
maps:values(UpdateFunctionMaps)
maps:size(UpdateFunctionMaps)
maps:without([1, 2, "Good"], UpdateFunctionMaps)
maps:remove("Good", UpdateFunctionMaps)
(6)
Accumulation =
maps:fold(fun(Key, Value, Acc) when is_list(Key) ->
Acc ++ atom_to_list(Value)
end, [], FunctionMap),
IceCream = maps:from_list([{"ha", 1}, {"gen", 2}, {"da", 3}, {"si", 4},
{"Good", 5}]),
(7)Fun = fun(K, V) when is_list(K) -> V*10 end,
maps:map(Fun, IceCream)
maps:merge(IceCream, FunctionMap)
maps:to_list(IceCream)
(8)
MarkMap = #{"fool" => me, "lazy" =>i},
PutMarkMap = MarkMap#{"Put" => put}
UpdateMarkMap = PutMarkMap#{"Put" := update}

{"Put" := Put} = UpdateMarkMap,


在Shell 下就可以直接测试的, 就是用了下gen_server的框架测了,

测试代码

-module(testmaps).
-behaviour(gen_server).
-export([start/0, stop/0]).
-export([mark_operation/0,
test_function_maps/0]).
-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3]).
% -compile(export_all).
-record(state, {markmap, functionmap}).

%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
start() ->
FunctionMap = maps:new(),
MarkMap = #{"fool" => me, "lazy" =>i},
io:format("new FunctionMap = pn", [FunctionMap]),
io:format("new MarkMap = pnnn", [MarkMap]),
gen_server : start_link({local, ?MODULE}, ?MODULE,
[FunctionMap, MarkMap], []).

stop() ->
gen_server : call(?MODULE, stop).

%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
mark_operation() ->
gen_server : call(?MODULE, mark_operation).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
test_function_maps() ->
function_put("Good", weather),
function_find(well),
function_find("Good"),
function_get_default(genious, you_are_not_genious),
thekeys(great),
list_of_maps().

function_put(Key, Value) ->
gen_server : call(?MODULE, {function_put, Key, Value}).

function_find(Key) ->
gen_server : call(?MODULE, {function_find, Key}).

function_get_default(genious, you_are_not_genious) ->
gen_server : call(?MODULE, {function_get_default, genious,
you_are_not_genious}).

thekeys(great) ->
gen_server : call(?MODULE, {thekeys, great}).

list_of_maps() ->
gen_server : call(?MODULE, list_of_maps).

%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
init( [FunctionMap, MarkMap]) ->
{ok, #state{functionmap = FunctionMap, markmap = MarkMap}}.

handle_call(mark_operation, _From, State) ->
%%there are five operations in maps
%% new put get find update
#state{markmap = MarkMap} = State,
io:format("the original MarkMap is pn", [MarkMap]),
PutMarkMap = MarkMap
io:format("after put the MarkMap is pn", [PutMarkMap]),
UpdateMarkMap = PutMarkMap#{"Put" := update},
io:format("after put the MarkMap is pn", [UpdateMarkMap]),
%% this mean get/2 ,but is syntax error,don't know why
% io:format("mark get Put is pn", [UpdateMarkMap#{"Put"}]),
%% this means find/2
#{"Put" := Put} = UpdateMarkMap,
io:format("mark "Put" find is pn", [Put]),
{reply, ok, State#state{functionmap = UpdateMarkMap}};

handle_call({function_put, Key, Value}, _From, State) ->
#state{functionmap = FunctionMap} = State,
Putfunctionmap = maps:put(Key, Value, FunctionMap),
io:format("after put functionmaps is pn", [Putfunctionmap]),
{reply, ok, State#state{functionmap = Putfunctionmap}};

handle_call({function_get_default, genious, you_are_not_genious}, _From, State) ->
#state{functionmap = FunctionMap} = State,

try maps:get(genious, FunctionMap, you_are_not_genious) of
      GeniousValue ->
          io:format("get genious the result is  ~p~n", [GeniousValue])
catch
    exit:Exit ->
          io:format("Get Exit, The Reason is ~p~n", [Exit]);
    %%undef is error ,not exit
    error:Error ->
          io:format("when use maps:get/3 Get Error, The error is ~p~n", [Error])
end,
io:format("~n"),
{reply, ok,  State};

handle_call({function_find, Key}, _From, State) ->
#state{functionmap = FunctionMap} = State,
try maps:get(Key, FunctionMap) of
GotValue ->
io:format("get ~p => pn", [Key, GotValue])
catch
%%will fail with an exception,in erlang show error?????
%% not throw!!!
error:Error ->
io:format("get Error: pn", [Error]);
throw:Exception ->
io:format("get exception pn", [Exception])
end,
case maps:find(Key, FunctionMap) of
{ok, FoundValue} ->
io:format("find ~p => ~p is in FunctionMap ~n", [Key, FoundValue]);
error ->
io:format("find ~p not exits in FunctionMap~n", [Key]);
_ ->
io:format("impossible return for maps:findnn")
end,
io:format("~n"),
{reply, ok, State};

handle_call({thekeys, great}, _From, State) ->
#state{functionmap = FunctionMap} = State,
io:format("great is one of the keys of functionmap = pn",
[maps:is_key(great, FunctionMap)]),
io:format("All keys of FunctionMap is -> pn", [maps:keys(FunctionMap)]),
PutFunctionMaps = maps:put("lovely", smile, FunctionMap),
UpdateFunctionMaps = maps:update("Good", rain, PutFunctionMaps),
io:format("After update All Values of FunctionMap is -> pn",
[maps:values(UpdateFunctionMaps)]),
io:format("now the size of function is pn",
[maps:size(UpdateFunctionMaps)]),
% io:format("test with function = pn",
% [maps:with([1, 2, "Good"], UpdateFunctionMaps)]),
io:format("test without function = pn",
[maps:without([1, 2, "Good"], UpdateFunctionMaps)]),
io:format("after remove Good, the functionmap is pn",
[maps:remove("Good", UpdateFunctionMaps)]),
{reply, ok, State#state{functionmap = UpdateFunctionMaps}};

handle_call(list_of_maps, _From, State) ->
#state{functionmap = FunctionMap} = State,
Accumulation =
maps:fold(fun(Key, Value, Acc) when is_list(Key) ->
Acc ++ atom_to_list(Value)
end, [], FunctionMap),
io:format("map:fold =>Acc VAlue is pn", [Accumulation]),

IceCream = maps:from_list([{"ha", 1}, {"gen", 2}, {"da", 3}, {"si", 4}, 
                                 {"Good", 5}]),
io:format("maps:from_list,but the sequence is unpredictable=> ~p~n", [IceCream]),
Fun = fun(K, V) when is_list(K) -> V*10 end,
io:format("maps:map=> ~p~n", [maps:map(Fun, IceCream)]),
%% Merges two maps into a single map Map3. If two keys exists in both maps
%% the value in Map1 will be superseded by the value in Map2.
io:format("maps:merge=>~p~n", [maps:merge(IceCream, FunctionMap)]),
io:format("map:to_list=>~p~n", [maps:to_list(IceCream)]),
{reply, ok, State};

handle_call(stop, _From, State) ->
{stop, normal, ok, State};

handle_call(_Request, _From, State) ->
{reply, ok, State}.

handle_cast(_Msg, State) ->
{noreply, State}.

handle_info(_Info, State) ->
io : format("~p", [_Info]),
{noreply, State}.

terminate(_Reason, _State) ->
ok.

code_change(_OldVsn, State, _Extra) ->
{ok, State}.

测试结果

Erlang/OTP 17 [erts-6.0] [source] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V6.0 (abort with ^G)
1> c(testmaps).
{ok,testmaps}
2> testmaps:start().
new FunctionMap = #{}
new MarkMap = #{"fool" => me,"lazy" => i}

{ok,<0.40.0>}
3> testmaps:test_function_maps().
after put functionmaps is #{"Good" => weather}
get Error: bad_key
find well not exits in FunctionMap

get "Good" => weather
find "Good" => weather is in FunctionMap

when use maps:get/3 Get Error, The error is undef

great is one of the keys of functionmap = false
All keys of FunctionMap is -> ["Good"]
After update All Values of FunctionMap is -> [rain,smile]
now the size of function is 2
test without function = #{"lovely" => smile}
after remove Good, the functionmap is #{"lovely" => smile}
map:fold =>Acc VAlue is "rainsmile"
maps:from_list,but the sequence is unpredictable=> #{"Good" => 5,
"da" => 3,
"gen" => 2,
"ha" => 1,
"si" => 4}
maps:map=> #{"Good" => 50,"da" => 30,"gen" => 20,"ha" => 10,"si" => 40}
maps:merge=>#{"Good" => rain,"da" => 3,"gen" => 2,"ha" => 1,"lovely" => smile,"si" => 4}
map:to_list=>[{"Good",5},{"da",3},{"gen",2},{"ha",1},{"si",4}]
ok
4> testmaps:mark_operation().
the original MarkMap is #{"fool" => me,"lazy" => i}
after put the MarkMap is #{"Put" => put,"fool" => me,"lazy" => i}
after put the MarkMap is #{"Put" => update,"fool" => me,"lazy" => i}
mark "Put" find is update
ok
5>

原文地址:https://www.cnblogs.com/ShankYan/p/4136414.html