這種技術被稱爲合併連接。它在數據庫設計中是衆所周知的。
merge(L1, L2) ->
merge_(lists:sort(L1), lists:sort(L2)).
merge_([{K, V1}|T1], [{K, V2}|T2]) -> [{K, [V1, V2]}|merge_(T1, T2)];
merge_([], []) -> [].
如果可以有不同的套在兩個列表按鍵,你願意放棄這些價值,你可以使用
merge_([{K, V1}|T1], [{K, V2}|T2]) -> [{K, [V1, V2]}|merge_(T1, T2)];
merge_([{K1, _}|T1], [{K2, _}|_]=L2) when K1 < K2 -> merge_(T1, L2);
merge_(L1, [{_, _}|T2]) -> merge_(L1, T2);`
merge_(_, []) -> [].
或者,如果你想儲存在名單上的這些值
merge_([{K, V1}|T1], [{K, V2}|T2]) -> [{K, [V1, V2]}|merge_(T1, T2)];
merge_([{K1, V1}|T1], [{K2, _}|_]=L2) when K1 < K2 -> [{K1, [V1]}|merge_(T1, L2)];
merge_(L1, [{K2, V2}|T2]) -> [{K2, [V2]}|merge_(L1, T2)];
merge_(L1, []) -> [{K, [V]} || {K, V} <- L1].
你當然可以使用尾遞歸版本,如果你不介意結果相反,或者你總是可以使用lists:reverse/1
merge(L1, L2) ->
merge(lists:sort(L1), lists:sort(L2), []).
merge([{K, V1}|T1], [{K, V2}|T2], Acc) -> merge(T1, T2, [{K, [V1, V2]}|Acc]);
merge([], [], Acc) -> Acc. % or lists:reverse(Acc).
或者
merge([{K, V1}|T1], [{K, V2}|T2], Acc) -> merge(T1, T2, [{K, [V1, V2]}|Acc]);
merge([{K1, _}|T1], [{K2, _}|_]=L2, Acc) when K1 < K2 -> merge(T1, L2, Acc);
merge(L1, [{_, _}|T2], Acc) -> merge(L1, T2, Acc);`
merge(_, [], Acc) -> Acc. % or lists:reverse(Acc).
或者
merge([{K, V1}|T1], [{K, V2}|T2], Acc) -> merge(T1, T2, [{K, [V1, V2]}|Acc]);
merge([{K1, V1}|T1], [{K2, _}|_]=L2, Acc) when K1 < K2 -> merge(T1, L2, [{K1, [V1]}|Acc]);
merge(L1, [{K2, V2}|T2], Acc) -> merge(L1, T2, [{K2, [V2]}|Acc]);`
merge([{K1, V1}|T1], [], Acc) -> merge(T1, [], [{K1, [V1]} | Acc]);
merge([], [], Acc) -> Acc. % or lists:reverse(Acc).
% or merge(L1, [], Acc) -> lists:reverse(Acc, [{K, [V]} || {K, V} <- L1]).
% instead of two last clauses.
如果有可能,列出可以包含相同的密鑰願意和你收集的所有值,你可以考慮一下這款
merge(L1, L2) ->
merge(lists:sort(L1), lists:sort(L2), []).
merge([{K1, _}|_]=L1, {K2, _}|_]=L2, Acc) ->
K = min(K1, K2),
{Vs1, T1} = collect(K, L1, []),
{Vs2, T2} = collect(K, L2, Vs1),
merge(T1, T2, [{K, Vs2}|Acc]);
merge([{K, _}|_]=L1, [], Acc) ->
{Vs, T1} = collect(K, L1, []),
merge(T1, [], [{K, Vs}|Acc]);
merge([], [{K, _}|_]=L2, Acc) ->
{Vs, T2} = collect(K, L2, []),
merge([], T2, [{K, Vs}|Acc]);
merge([], [], Acc) -> lists:reverse(Acc).
collect(K, [{K, V}|T], Acc) -> collect(K, T, [V|Acc]);
collect(_, T, Acc) -> {Acc, T}.
謝謝@carlo和Berzemus的建議 –