2017-09-12 25 views
5

這是我的當前代碼的示例:erlang是否在列表中有一個隱藏的rownum?

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],如果我它更改爲列表:foldr相似,ReducedDataSet將是[3,4,5 ,6]。

我沒想到這是當其被吸收從左到右,第3個值是3,應繼續執行6,但是當吸收從右到左,第3個值是7,並繼續到4

這是否意味着我的列表中有一個隱藏的行號,foldl和foldr僅在最終列表的排序順序上有所不同?

回答

4

TL; DR

不,在Erlang列表中沒有隱藏索引或「行號」。

討論

它可能有助於探索在功能列表的上下文列表操作的性質多一點「名單是一堆conses之外的」品種。

我寫了褶皺的解釋而回,可能對你有用:Explanation of lists:fold function

請記住,功能僅列出有去單向指針。也就是,他們是單鏈表。沒有「rownum」或「index」的概念,因爲它會在C風格的數組中。每次調用lists:nth/2實際上是遍歷列表到 th元素返回該元素之前。

我們可以寫lists:nth/2這樣,如果我們想要一個壞輸入崩潰版本(和,看着它,事實證明,it is written almost exactly like this):

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

+0

認爲這回答我的問題,我問它最好。另一個答案是關於fold的快速提醒,但正如我自己意識到的,答案是要記住它是列表:第n個是確定列表中的位置。 – Philbo

+0

我也不是我們如何編寫多行函數的粉絲 - 我上面的寫法只反映了我們目前的工作方式。將你的鏈接發送給我的高級,看看它是否比我設法更有說服力。 – Philbo

+0

@Philbo並非所有人都同意我的觀點,即瓦解事物是一個好主意。我發現通常命名好的函數比內聯的函數更容易處理(並在其他地方找到),幾乎在所有情況下,爲更大函數內的匿名函數分配一個有意義的標籤幾乎總是一個可讀性勝利。然而,隨着時間的推移,這些可讀性會增加*特別是當您返回重新編寫一些舊代碼時。至於一般風格,我根據可用的灰鬍子建議爲此寫了一個示例項目:https://github.com/zxq9/zuuid – zxq9

4

我認爲這是一個更一般的fold的問題。

一般而言,折執行以下操作:(new_element, acc) -> new_acc

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

如果操作是「追加」,則將元素向左或向右追加是有區別的。

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

我從來不記得這是foldlfoldr但我認爲左/右指的是蓄電池的位置([3] ° 4foldl這一定義)

+2

說實話,隨着你的回答,我意識到我在這裏專注於錯誤的東西。正如你所說的foldl和foldr只是確定添加到累積新列表中的元素的位置,其列表:nth正在使用靜態原始DataSet並確定每個位置。要列出:第n個,第3個元素總是處於第3個位置,不管我在處理完該元素後做了什麼。 – Philbo