我有几个关键/值专家名单,如:
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个元素和元素可以按任何顺序排列。
答案 0 :(得分:6)
使用orddict模块,该模块明确适用于对列表:
orddict:merge(fun(_,X,Y) - > X + Y end,orddict:from_list(L1), orddict:from_list(L2))
更好的是,如果确保L1和L2始终按键排序,则在合并之前无需调用from_list(L)。
答案 1 :(得分: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.