簡體   English   中英

合並列表erlang的內部列表

[英]Merge inner lists of a list erlang

我有一個清單L.

L = [L1, L2, L3,...]. 

其中L1,L2,L3 ..本身就是列表,如下所示:

L1 = [{k1, 10}, {k2, 20}, {k3, 30}, {k4, 20.9}, {k6, "Hello world"}]

L2 = [{k1, 90}, {k2, 210}, {k3, 60}, {k4, 66.9}, {k6, "Hello universe"}]

L3 = [...]

現在我想要一個結果組合列表:

FinalList = [
       {k1, [10, 90, ...]}, % '...' denotes values from other lists
       {k2, [20, 210, ...]},
       {K3, [30, 60, ...]},
       {k4, [20.9, 66.9, ...]},
       {K6, ["Hello world", "Hello universe", ...]}
     ]

我可以使用我的Old Posts解決方案進行合並合並/合並兩個Erlang列表但是我不確定如何將L (列表列表)傳遞給該合並函數。

先感謝您!

您可以使用lists:foldlmerge應用於列表列表。 這是一個例子:

-module(test).
-export([test/0]).


merge(L1, L2) ->
    merge_(lists:sort(L1), lists:sort(L2)).

merge_([{K, V1}|T1], [{K, V2}|T2]) when is_list(V1), is_list(V2)
    -> [{K, V1 ++ V2}|merge_(T1, T2)]; 
merge_([{K, V1}|T1], [{K, V2}|T2]) when is_list(V1)
    -> [{K, V1 ++ [V2]}|merge_(T1, T2)];
merge_([{K, V1}|T1], [{K, V2}|T2]) when is_list(V2)
    -> [{K, [V1] ++ V2}|merge_(T1, T2)];
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]) when is_list(V2)
   -> [{K2, V2}|merge_(L1, T2)];
merge_(L1, [{K2, V2}|T2]) 
   -> [{K2, [V2]}|merge_(L1, T2)];
merge_(L1, []) -> [{K, V} || {K, V} <- L1].


test() ->

  L1 = [{k1, 10}, {k2, 20}, {k3, 30}, {k4, 20.9}, {k6, "Hello world"}],
  L2 = [{k1, 90}, {k2, 210}, {k3, 60}, {k4, 66.9}, {k6, "Hello universe"}],
  L3 = [{k1, 45}, {k2, 35}, {k3, 37}, {k4, 77.9}, {k6, "Hello cosmo"}],
  lists:foldl(fun merge/2, [], [L1, L2, L3]).

以下是結果:

36> test:test().
[{k1,"-Z\n"},
 {k2,[35,210,20]},
 {k3,[37,60,30]},
 {k4,[77.9,66.9,20.9]},
 {k6,"Hello cosmoHello universeHello world"}]

如你看到的,

  1. 您需要修改merge函數來處理列表(不僅僅是原始問題中的原子)。 它已在我的示例代碼中完成,該代碼基於Vychodil的答案

  2. 您需要修改merge函數以正確處理字符串(如鍵k1和k6中的證據)。 你應該能夠自己解決它。

最后但同樣重要的是,您應該在解決問題時接受答案。 檢查此鏈接了解原因。

我得到了啟發,並得到了這個功能,假設所有列表都有相同的鍵(這似乎是這里的情況):

merge_lists([First|_]=ListOfLists) ->
    Keys = proplists:get_keys(First),
    lists:map(fun(Key) ->
                  {key,lists:flatmap(fun(List) -> 
                                         [proplists:get_value(Key,List)] 
                                         end
                                    ,ListOfLists)} 
                  end
             ,Keys).

請原諒格式化:此函數首先獲取它應該查找的鍵,然后按鍵編譯每個列表中的值列表(不需要以這種方式更新累加器)。 可能是一個單行,但這將是一個很長的路線;)

一些測試列表的結果(L3 = L1,但沒有密鑰k6 ,這就是未定義的原因):

1> test:merge_lists([L1,L3,L2]).
[{k1,"\n\nZ"},
 {k2,[20,20,210]},
 {k3,[30,30,60]},
 {k4,[20.9,20.9,66.9]},
 {k6,["Hello world",undefined,"Hello universe"]}]

編輯:這可能是一種更容易理解的格式。 看起來也更好:

merge_lists([First|_]=ListOfLists) ->
    MapKeys = fun(Key) -> 
                MapLists = fun(List) -> [proplists:get_value(Key,List)] end,
                Values   = lists:flatmap(MapLists ,ListOfLists),
                {Key,Values} end,
    lists:map(MapKeys,proplists:get_keys(First)).

Berzemus對鏈接問題的回答很容易適應:

merge(ListOfLists) ->
    Combined = lists:append(ListOfLists),
    Fun      = fun(Key) -> {Key,proplists:get_all_values(Key,Combined)} end,
    lists:map(Fun,proplists:get_keys(Combined)).

但是,如果L有許多列表或者它們很長,這將是非常低效的。 在這種情況下,您應該從Vychodil的解決方案開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM