【问题标题】:Merge inner lists of a list erlang合并列表erlang的内部列表
【发布时间】:2014-03-19 13:09:54
【问题描述】:

我有一个列表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 Solutions:Combine/Merge Two Erlang lists 进行合并,但我不确定如何将 L(列表列表)传递给该合并函数。

提前谢谢你!

【问题讨论】:

  • @AnthonyKong:不重复!这是一个不同的问题,请阅读。
  • @LaxmikantGumalkar 好的,我收回了“可能的重复”。我想你可以让你的问题更清楚。我的第一印象是你在传递两个参数来合并时遇到了麻烦。但您的问题实际上是关于将超过 2 个元素的列表传递给函数merge
  • 所有列表都有相同的键吗?这很重要,因为它使问题变得容易得多。
  • @LaxmikantGurnalkar 简单!看看下面我的建议。顺便说一句:正如安东尼所说,不要忘记接受可以解决您问题的答案。

标签: list merge erlang


【解决方案1】:

我受到启发,并得到了这个工作功能,假设所有列表都有相同的键(这里似乎就是这种情况):

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)).

【讨论】:

    【解决方案2】:

    您可以使用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's answer

    2. 您需要修改 merge 函数以正确处理字符串(作为键 k1 和 k6 中的证据)。你应该可以自己修复它。

    最后但并非最不重要的一点是,当它解决了您的问题时,您应该接受答案。查看this link 了解原因。

    【讨论】:

      【解决方案3】:

      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 的解决方案开始。

      【讨论】:

        猜你喜欢
        • 2014-03-19
        • 1970-01-01
        • 1970-01-01
        • 2020-01-21
        • 1970-01-01
        • 1970-01-01
        • 2021-11-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多