【问题标题】:Custom concatenation of inner list Erlang内部列表Erlang的自定义连接
【发布时间】:2014-04-28 12:04:12
【问题描述】:

我有一些表单的大列表,其中包含需要与来自其他同名表单的其他数据连接的数据。

列表格式相当复杂,如下所示:

[[{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

eg.这是我的示例数据:

[[{"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">>]}]}}]

【问题讨论】:

  • 您的预期结果与{'F_01_0090',[["2"], ["3"]]} different of {'F_01_0010',[[&lt;&lt;"4 - 1"&gt;&gt;], &lt;&lt;"4 - 8"&gt;&gt;]} 存在一些不一致,如果您想将所有结果合并到一个资产中,您还应该澄清您是否想要像{'F_01_0050',[[], []]} 而不是{'F_01_0050',[[]]} 这样的重复结果,即使它们出现在一个单一的或如果键列表在每个资产中始终相同。
  • @Pascal:对不起,那是我的错误。现在请检查它是否已更正。

标签: erlang concatenation


【解决方案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).

【讨论】:

  • :你的代码很漂亮。感谢您的解决方案,我有一个问题,我想要一个最低的评估表格编号,即结果应该显示为“eval_data_11”。在上述情况下会发生这种情况。但是当我在我的项目中使用这个代码时,我没有得到最低的评估表格编号。由于客户端级别的 javascript 抛出错误。
  • 在答案中查看修改后的版本
【解决方案2】:

@trex:

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

您需要获得一个单独的列表,该列表具有常见的表单名称为&lt;&lt;"prvl_mobable_asset_0000_h200401"&gt;&gt;

{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 = 列表: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)).

【讨论】:

    猜你喜欢
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多