通过fold erlang在元组的不同列表中收集多个值

时间:2014-09-19 03:14:22

标签: erlang fold

我必须迭代一个包含像Sequence = ["1","2","4","5"]这样的列表中元素的序列。需要准备9个列表,这些列表只能从Sequence计算出来。我跟随折叠。

Accumulators = {[], [], [], [], [], [], [], [], []},
ReturnedTup = lists:foldl(fun(Seq, Acc) ->
       {AccF1,AccF2,AccF3, AccF4,AccF5,AccF6, AccF7,AccF8,AccF9} = Acc,
       F1 = get_seq_indexlist(Seq, "F1"),
       F2 = get_seq_indexlist(Seq, "F2"),
       F3 = get_seq_indexlist(Seq, "F3"),
       ...
       F9 = get_seq_indexlist(Seq, "F9"),
       [F1|AccF1], [F2|AccF2], [F3|AccF3], ...,[F9|AccF9],
       Acc      
     end, Accumulators, Sequence),
io:format("~p ReturnedTup", [ReturnedTup]).

但在这里,我ReturnedTup为空{[], [], [], [], [], [], [], [], []}。我不确定它有什么不对。我在F1, F2, F3... F9中获得了正确的值。

我是erlang的新手。可以有效地实现这一目标。如果是这样,请告诉我。

2 个答案:

答案 0 :(得分:1)

你在foldl中的函数总是返回初始累加器:

Acc

您需要返回新的acc,它必须是包含更新列表的元组。:

Accumulators = {[], [], [], [], [], [], [], [], []},
ReturnedTup = lists:foldl(fun(Seq, Acc) ->
       {AccF1,AccF2,AccF3, AccF4,AccF5,AccF6, AccF7,AccF8,AccF9} = Acc,
       F1 = get_seq_indexlist(Seq, "F1"),
       F2 = get_seq_indexlist(Seq, "F2"),
       F3 = get_seq_indexlist(Seq, "F3"),
       ...
       F9 = get_seq_indexlist(Seq, "F9"),
       {[F1|AccF1], [F2|AccF2], [F3|AccF3], ...,[F9|AccF9]}
     end, Accumulators, Sequence),

答案 1 :(得分:1)

Rubber Cthulu的答案才刚刚开始:)

删除代码重复会很好。如果你复制粘贴九次 - 很难维护。

Sequence = ["1","2","4","5"],
Accumulators = [[], [], [], [], [], [], [], [], []],
CounterToString = fun(Integer) -> "F"++integer_to_list(Integer) end,
FoldlFun = fun(SequenceElement, Acc) ->
                   PrependSeqIndexList = fun(Counter, InnerAcc) ->
                                                [get_seq_indexlist(SequenceElement, CounterToString(Counter)) | InnerAcc] end,
                   {NewAccs, _LastCounter} = lists:mapfoldl(fun(InnerAcc, Counter) ->
                                                                    {PrependSeqIndexList(Counter, InnerAcc),
                                                                     Counter+1} end, 1, Acc),
                   NewAccs
           end,
ReturnedList = lists:foldl(FoldlFun, Accumulators, Sequence),
ReturnedTup = list_to_tuple(ReturnedList),
io:format("~p ReturnedTup", [ReturnedTup]).
  • 我会将Seq更改为SequenceElement,因为函数,即foldl/3的参数需要序列元素,而不是整个序列。或者您可以将其命名为InnerSequence - 无所谓。
  • 您希望迭代内部累加器,因此将它们设为列表
  • 使用mapfoldl迭代内部累加器 - 它的工作方式与map类似,但它也有累加器,我们将用于计数器。
  • 如果你真的需要在元组中返回值,请在末尾使用list_to_tuple/1
  • 为助手命名,这样可以更轻松地阅读代码。
  • 如果你在另一个乐趣中创造乐趣,你可以使用外部乐趣参数。 PrependSeqIndexList使用SequenceElement,即使它位于外部范围内。它被称为封闭。
  • 还有其他方法可以改进这段代码 - 例如,它仍然是深层嵌套的,但我把它作为练习留给你:)