erlang在列表中有隐藏的rownum吗?

时间:2017-09-12 08:37:04

标签: erlang

这是我当前代码的示例:

DataSet = [1,2,3,4,5,6,7,8,9].

Sequence = [3,4,5,6].

ReducedDataSet = lists:foldl( fun(SeqNumber, Output) ->
                                 Row = lists:nth(SeqNumber, DataSet),
                                 [Row|Output]
                              end,
                              [],
                              Sequence
                             ).

ReducedDataSet最终为[6,5,4,3],如果我将其更改为list:foldr,ReducedDataSet将为[3,4,5,6]。

我没想到这是因为从左到右吸收,第3个值是3并且应该进入6,但是当从右到左吸收时,第3个值将是7,并且继续到4。

这是否意味着我的列表中存在隐藏的行号,而foldl和foldr仅在最终列表的排序顺序上有所不同?

2 个答案:

答案 0 :(得分:4)

我认为这是一个更普遍的fold问题。

通常,fold会执行以下操作:(new_element, acc) -> new_acc

如果操作new_element ° acc是可交换的(例如sum),则foldl和foldr是相同的。

如果操作是“追加”,则将元素添加到左侧或右侧之间存在差异。

[3] ° 4 -> [3, 4] VS 4 ° [3] -> [4, 3]

我永远不会记得哪个是foldlfoldr,但我认为左/右指的是累加器的位置([3] ° 4foldl这个定义)

答案 1 :(得分:3)

<强> TL; DR

不,Erlang列表中没有隐藏索引或“行号”。

<强>讨论

在“列表是一堆事物”的功能列表的上下文中,更多地探索列表操作的本质可能会有所帮助。

我写了一篇关于折叠的解释,可能对你有用:Explanation of lists:fold function

请记住,功能列表只有指向单向的指针。也就是说,它们是单链表。没有“rownum”或“index”的概念,因为它将在C样式数组中。每次调用lists:nth/2实际上遍历列表 n 元素,然后返回该元素。

如果我们想要一个在错误输入上崩溃的版本(并且查找它,结果是it is written almost exactly like this),我们可以这样写lists:nth/2

nth(1, [Element | _]) ->
    Element;
nth(N, [_ | Rest]) when N > 1 ->
    lists:nth(N - 1, Rest).

(作为旁注,请考虑not inlining funs that require you to write multi-line definitions as function arguments ...)