内部列表Erlang的自定义连接

时间:2014-04-28 12:04:13

标签: erlang concatenation

我有一些包含数据的表单的大清单,这些表单需要与来自其他同名表单的其他数据进行比较。

列表格式非常复杂,如下所示:

[[{EVAL_SEQ_1, {FORMNAME, ListDataToConcat1}}], [{EVAL_SEQ_2, {FORMNAME, ListDataToConcat2}}], ...]

这是我想要的输出:

[[{EVAL_SEQ_1,{FORMNAME,ListDataToConcat1 + ListDataToConcat2}}]}}] ...]

其中:

EVAL_SEQ_1 = Form Sequence Number,
FORMNAME = Form Name
ListDataToConcat = List that Needs to concat

例如。这是我的样本数据:

[[{"eval_data_12",
    {<<"prvl_mobable_asset_0000_h200401">>,
     [{'F_01_0100',[1]},
      {'F_01_0090',["3"]},
      {'F_01_0080',[]},
      {'F_01_0070',[9999]},
      {'F_01_0060',[{era,0},{year,[]},{month,[]}]},
      {'F_01_0050',[]},
      {'F_01_0040',[]},
      {'F_01_0030',[]},
      {'F_01_0020',<<>>},
      {'F_01_0010',<<"4 - 8">>}]}}],
  [{"eval_data_11",
    {<<"prvl_mobable_asset_0000_h200401">>,
     [{'F_01_0100',[]},
      {'F_01_0090',["2"]},
      {'F_01_0080',[]},
      {'F_01_0070',[22222]},
      {'F_01_0060',[{era,0},{year,[]},{month,[]}]},
      {'F_01_0050',[]},
      {'F_01_0040',[]},
      {'F_01_0030',[]},
      {'F_01_0020',<<>>},
      {'F_01_0010',<<"4 - 1">>}]}}], ...]

我希望结果输出如下:

[{"eval_data_11",
   {<<"prvl_mobable_asset_0000_h200401">>,
         [{'F_01_0100',[[], [1]]},
          {'F_01_0090',[["2"], ["3"]]},
          {'F_01_0080',[[], []]},
          {'F_01_0070',[[22222], [9999]]},
          {'F_01_0060',[[{era,0},{year,[]},{month,[]}], [{era,0},{year,[]},{month,[]}]]},
          {'F_01_0050',[[], []]},
          {'F_01_0040',[[], []]},
          {'F_01_0030',[[], []]},
          {'F_01_0020',[[<<>>], [<<>>]]},
          {'F_01_0010',[[<<"4 - 1">>], [<<"4 - 8">>]}]}}]

2 个答案:

答案 0 :(得分:1)

@trex:

FormList = [[{EVAL_SEQ_1, {FORMNAME, ListDataToConcat1}}], [{EVAL_SEQ_2, {FORMNAME, ListDataToConcat2}}], ....]

您需要单独列出具有<<"prvl_mobable_asset_0000_h200401">>

的常用表单名称的列表
{MobableList, EvalDataList} = lists:partition(fun([{EVAL_SEQ, {FORMNAME, ListData}}]) -> 
            FORMNAME == <<"prvl_mobable_asset_0000_h200401">>
         end, FormList),

然后,获取单独的表单序列和列表元组。将它们分开

{EvalSeq, MergingList} = lists:foldl(fun(X, {EvalNames, OutList}) -> 
                [{EVAL_SEQ, {FORMNAME, ListData}}] = X,
                {[EVAL_SEQ|EvalNames], [ListData|OutList]}
             end, {[], []}, MobableList),

因此,您将获得新的元组:

{[EVAL_SEQ_1, EVAL_SEQ_2, EVAL_SEQ_3, ...], [ListDataToConcat1, ListDataToConcat2, ListDataToConcat3,...]}

我不确定你想要哪个序列号,因为你没有清楚地提到它,这是你获得最小序列号的方法。                 Evalsequence = lists:min(EvalSeq),

现在使用merge功能合并您的代码,如下所示,或者您可以参考merging inner list Merge inner lists of a list erlang

    MergedList = merge(MergingList),

最后是一个单独的列表:

[{Evalsequence, {<<"prvl_mobable_asset_0000_h200401">>, MergedList}}].


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

答案 1 :(得分:1)

我建议你这个解决方案:

<强> [编辑]

我修改了代码来回答你的上一条评论,还有一些模糊的东西:

  • 如果资产不同,会创建不同的记录列表吗?
  • 如果不是应该用资产名称做什么?我选择保留“最小的一个”
  • 是重要的记录顺序 - 我决定不

一句话,我错过了一些上下文,但如果我添加收集这些信息,我会将其存储在ets表中。如果需要,更新更快,易于遍历,并且易于转换为列表。

-module (t).

-compile([export_all]).

%      rec = {atom,term}
%      reclist = [rec,...]
%      asset = {bin,reclist}
%      eval_data = [{list,asset}]
%      eval_set = [eval_data,...]
%      recs = {atom,[term]}
%      recslist = [recs,...]

addrec({Key,Val},Recslist) ->
    Val_list = proplists:get_value(Key, Recslist, []),
    [{Key,[Val|Val_list]}|proplists:delete(Key,Recslist)].

merge_rec(Reclist,Recslist) -> lists:foldl(fun(Rec,Acc) -> addrec(Rec,Acc) end,Recslist,Reclist).


merge_eval([{Eval,{Asset,Reclist}}],[]) ->
    [{Eval,{Asset,[{Key,[Val]} || {Key,Val} <- Reclist]}}];
merge_eval([{Eval,{Asset,Reclist}}],[{Eval_low,{Asset_low,Recslist}}]) ->
    [{min(Eval,Eval_low),{min(Asset,Asset_low),merge_rec(Reclist,Recslist)}}].

merge_set(Eval_set) -> lists:foldl(fun(Eval_data,Acc) -> merge_eval(Eval_data,Acc) end,[],Eval_set).

test() ->
    Eval_set =  [[{"eval_data_10",
                {<<"prvl_mobable_asset_0000_h200401">>,
                 [{'F_01_0100',[1]},
                  {'F_01_0090',["3"]},
                  {'F_01_0080',[]},
                  {'F_01_0070',[9999]},
                  {'F_01_0060',[{era,0},{year,[]},{month,[]}]},
                  {'F_01_0050',[]},
                  {'F_01_0040',[]},
                  {'F_01_0030',[]},
                  {'F_01_0020',<<>>},
                  {'F_01_0010',<<"4 - 8">>}]}}],
              [{"eval_data_11",
                {<<"prvl_mobable_asset_0000_h200401">>,
                 [{'F_01_0100',[]},
                  {'F_01_0090',["2"]},
                  {'F_01_0080',[]},
                  {'F_01_0070',[22222]},
                  {'F_01_0060',[{era,0},{year,[]},{month,[]}]},
                  {'F_01_0050',[]},
                  {'F_01_0040',[]},
                  {'F_01_0030',[]},
                  {'F_01_0020',<<>>},
                  {'F_01_0010',<<"4 - 1">>}]}}]],
    merge_set(Eval_set).