2

次のようなキー/値のプロパティ リストがいくつかあります。

    L1 = [{k1, 1}, {k2, 2}, ... {k32, 32}],
    L2 = [{k32, 0.1}, {k31, 0.2}, ... {k1, 0.32}].

キーでマージする効果的な方法は何ですか? 現在、私はそれが好きです:

    MergeFun = fun(_, X, Y) -> X+Y end,
    D1 = dict:from_list(L1),
    D2 = dict:from_list(L2),
    Res = dict:to_list(dict:merge(MergeFun, D1, D2)).

しかし、それはかなり遅いです。入力リストはそれほど大きくないと思います。おそらく 32 ~ 64 個の要素と要素が任意の順序である可能性があります。

4

2 に答える 2

6

ペアのリストで明示的に機能する orddict モジュールを使用します。

orddict:merge(fun(_,X,Y) -> X+Y end, orddict:from_list(L1), orddict:from_list(L2))。

さらに良いことに、L1 と L2 が常にキー順に並べられていることを確認すると、マージする前に from_list(L) を呼び出す必要がなくなります。

于 2012-04-26T10:00:19.603 に答える
1

これらの 2 つのリストを並べ替えてから、1 つの単純な関数にマージします。今のところ、これを行うためのより高速な方法はありません。

test() ->
    L1 = [{k1, 1}, {k2, 2}, {k32, 32}],
    L2 = [{k32, 0.1}, {k2, 0.2},  {k1, 0.32}],
    MergeFun = fun(X, Y) -> X+Y end,    
    merge(MergeFun, L1, L2).

merge(Fun, L1, L2) ->
    my_marge(Fun, lists:keysort(1, L1), lists:keysort(1, L2), []).

my_marge(Fun, [{Key, V1} | L1], [{Key, V2} | L2], Acc) ->
    my_marge(Fun, L1, L2, [{Key, Fun(V1, V2)} | Acc]);

my_marge(Fun, [], [{Key, V} | L], Acc) ->
    my_marge(Fun, [], L, [{Key, V} | Acc]);

my_marge(Fun, [{Key, V} | L], [], Acc) ->
    my_marge(Fun,L,[], [{Key, V} | Acc]);

my_marge(Fun, [{Key1, V1} | L1], [{Key2, V2} | L2], Acc) when Key1 < Key2 ->
    my_marge(Fun, L1, [{Key2, V2} | L2], [{Key1, V1} | Acc]);

my_marge(Fun, L1, [{Key, V} | L2], Acc) ->
    my_marge(Fun, L1, L2, [{Key, V} | Acc]);

my_marge(_Fun, [], [], Acc) ->
    Acc.
于 2012-04-26T10:51:31.087 に答える