zoukankan      html  css  js  c++  java
  • 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>

  • 相关阅读:
    Python-属性描叙符协议ORM实现原理依据- __set__ __get__ __delete__
    Python-类属性查询协议-__getattr__ __getattribute__
    Python-__init__ 和 __new__区别和原理
    Python-在不在判断 in 和 in判断协议- in __contains__
    Python-求序列长度和序列长度协议-len() __len__
    Python-序列反转和序列反转协议-reversed __reversed__
    Python-序列切片原理和切片协议-[start:end:step] __getitem__
    Python-序列常用方法 + * += extend append方法区别
    Python其他数据结构collection模块-namtuple defaultdict deque Queue Counter OrderDict arrary
    Python-函数式编程-map reduce filter lambda 三元表达式 闭包
  • 原文地址:https://www.cnblogs.com/ShankYan/p/4136414.html
Copyright © 2011-2022 走看看