2012-04-26 38 views
2

合併我有一對夫婦鍵/值propper列表,像:有效的鍵/值列表在二郎山

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個元素和元素可以以任何順序排列。

回答

6

使用orddict模塊,其中明確適用於對列表:

orddict:合併(樂趣(_,X,Y) - > X + Y端,orddict:from_list(L1), orddict:from_list(L2))。

更好的是,如果確保L1和L2總是按鍵排序,則在合併之前不需要調用from_list(L)。

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.