[erlang-questions] Merging maps with a fun like dict:merge/3

Hynek Vychodil vychodil.hynek@REDACTED
Wed Aug 26 11:32:00 CEST 2015


I would consider:

merge_ap(F, [Head | Tail]) ->
    lists:foldl(fun(Y, X) ->
                        maps:merge(X, maps:map(fun(Key, Value) ->
                                                       case maps:find(Key,
X) of
                                                           {ok, V} ->
F(Key, V, Value);
                                                           error    -> Value
                                                       end
                                               end,
                                               Y))
                end,
                Head,
                Tail).

On Wed, Aug 26, 2015 at 10:45 AM, Ivan Uemlianin <ivan@REDACTED> wrote:

> Dear Alexander
>
> Thanks!  That looks excellent!
>
> I notice that your function F is different from the dict:merge/3
> function: instead of taking a key and the two values, is takes two values,
> defaulting the first to 0.
>
> I've put my case clause into your framework:
>
> merge_ap(F, [Head | Tail]) ->
>     lists:foldl(fun(Y, X) ->
>                         maps:merge(X, maps:map(fun(Key, Value) ->
>                                                        case
> maps:is_key(Key, X) of
>                                                            false ->
>                                                                Value;
>                                                            true ->
>                                                                F(Key,
> Value, maps:get(Key, X))
>                                                        end
>                                                end,
>                                                Y))
>                 end,
>                 Head,
>                 Tail).
>
> This has desired behaviour, and will probably still perform well.  Using
> lists:foldl is a brilliant idea.
>
> Best wishes
>
> Ivan
>
>
>
> On 26/08/2015 09:16, Alexander Petrovsky wrote:
>
> Hi!
>
> I've make some little benchmarks, and noticed that the most effective way
> is:
>
> merge(F, [Head | Tail]) ->
>     lists:foldl(fun(Y, X) -> maps:merge(X, maps:map(fun(Key, Value) -> F(
> maps:get(Key, X, 0), Value) end, Y)) end, Head, Tail).
>
>
> 2015-08-23 20:05 GMT+03:00 Ivan Uemlianin <ivan@REDACTED>:
>
>> Dear All
>>
>> The maps module does not have a merge/3 like dict:merge/3, which calls a
>> function fun(Key, Val1, Val2) when both dicts have the same key.  From the
>> documentation, "If a key occurs in both dictionaries then Fun is called
>> with the key and both values to return a new value."
>>
>> The dict documentation says that dict:merge/3 is faster than an
>> equivalent implemented in erlang.
>>
>> http://www.erlang.org/doc/man/dict.html#merge-3
>>
>> Why does the maps module not have a similar merge/3?  Is it because
>> writing our own erlang implementation is at fast as it gets?
>>
>> Below is an implementation which seems to work.  Can it be made faster?
>>
>>
>> merge_maps(Fun, M1, M2) ->
>>     maps:fold(fun(K, V1, Acc) ->
>>                       case maps:is_key(K, Acc) of
>>                           false ->
>>                               maps:put(K, V1, Acc);
>>                           true ->
>>                               V2 = maps:get(K, Acc),
>>                               maps:put(K, Fun(K, V1, V2), Acc)
>>                       end
>>               end,
>>               M1,
>>               M2).
>>
>> merge_maps_test() ->
>>     merge_maps(fun(_K, V1, V2) -> V1 + V2 end,
>>                #{a => 1, b => 2, c => 3},
>>                #{b => 2, c => 3, d => 4}) =:=
>>         #{a => 1, b => 4, c => 6, d => 4}.
>>
>>
>> With thanks and best wishes
>>
>> Ivan
>>
>> --
>> ============================================================
>> Ivan A. Uemlianin PhD
>> Llaisdy
>> Speech Technology Research and Development
>>
>>                     ivan@REDACTED
>>                         @llaisdy
>>                          llaisdy.wordpress.com
>>               github.com/llaisdy
>>                      www.linkedin.com/in/ivanuemlianin
>>
>>                         festina lente
>> ============================================================
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>
>
>
> --
> Петровский Александр / Alexander Petrovsky,
>
> Skype: askjuise
> Phone: +7 914 8 820 815
>
>
> --
> ============================================================
> Ivan A. Uemlianin PhD
> Llaisdy
> Speech Technology Research and Development
>
>                     ivan@REDACTED
>                         @llaisdy
>                          llaisdy.wordpress.com
>               github.com/llaisdy
>                      www.linkedin.com/in/ivanuemlianin
>
>                         festina lente
> ============================================================
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150826/65c39324/attachment.htm>


More information about the erlang-questions mailing list