2015-11-17 40 views
4

試圖瞭解Elixir如何執行Enum.reduce,我將它插入一個put來觀察輸出。我不清楚它爲什麼首先執行第二個列表元素,而不是第一個,然後獨立執行所有其他列表元素。Elixir減少元素的順序

iex (30)> Enum.reduce([1,2,3,4], &(IO.puts("a#{&1} b#{&2}"))) 
a2 b1 
a3 bok 
a4 bok 

(A和B都只是爲了驗證順序)

查看源,我想它翻譯成

:lists.foldl(&IO.puts("a#{&1} b#{&2}"), 1, [2,3,4]) 

產生相同的結果。

其中1是最初的累加器,如果我給它一個函數來給它一些積累它的東西,會說出一些有趣的東西,而不是「bok」。

雖然反轉這些初始值讓我覺得很奇怪。我應該如何思考Reduce實施?

+0

source reference https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/enum.ex line 1475 –

回答

3

您正在使用Enum.reduce/2函數。將列表的第一個元素作爲累加器處理。只需在iex中鍵入h Enum.reduce/2即可。您將獲得以下輸出

Invokes fun for each element in the collection passing that element and the 
accumulator acc as arguments. fun's return value is stored in acc. The first 
element of the collection is used as the initial value of acc. If you wish to 
use another value for acc, use Enumerable.reduce/3. This function won't call 
the specified function for enumerables that are 1-element long. Returns the 
accumulator. 

Note that since the first element of the enumerable is used as the initial 
value of the accumulator, fun will only be executed n - 1 times where n is the 
length of the enumerable. 

Examples 

┃ iex> Enum.reduce([1, 2, 3, 4], fn(x, acc) -> x * acc end) 
┃ 24 

第二段應該澄清你的疑問

注意,由於枚舉的第一個元素被用作累加器的初始 價值,樂趣纔會執行n - 1次,其中n是可枚舉的長度。

+0

謝謝。這個問題源於試圖找出&2引用的內容(最初認爲它是該系列中的第二個元素)。現在我明白這是累加器。 –

+0

如果這對你有幫助,請立即註冊。如果您覺得這是合適的答案,請將其標記爲答案。 – coderVishal

+0

ACK。我沒有足夠的影響力在這個stackoverflow社區爲我的upvotes展示(還)。而現在我神奇地做:) –

2

有兩個Enum.reduce函數,Enum.reduce/2Enum.reduce/3Enum.reduce/3是採用可枚舉,初始累加器和減函數的通常減法函數。 Enum.reduce/2/3非常相似,但會跳過初始累加器,而是將可枚舉中的第一個元素作爲累加器,對於列表,它可以實現爲:def reduce([first|rest], fun), do: reduce(rest, first, fun)

+0

謝謝!我有一個使用Enum.reduce/3的小小的epihany,其累加器的值爲0,它以正確的順序顯示元素: Enum.reduce([1,2,3,4],1,&(IO。 puts(「a#{&1} b#{&2}」))) –