为了了解 Elixir 如何执行 Enum.reduce,我将其插入 puts 以观察输出。我不清楚为什么它首先执行第二个列表元素,而不是第一个,然后独立地逐步执行所有其他元素。
iex (30)> Enum.reduce([1,2,3,4], &(IO.puts("a#{&1} b#{&2}")))
a2 b1
a3 bok
a4 bok
Run Code Online (Sandbox Code Playgroud)
( a 和 b 只是为了验证订单)
查看源代码,我认为它可以转化为
:lists.foldl(&IO.puts("a#{&1} b#{&2}"), 1, [2,3,4])
Run Code Online (Sandbox Code Playgroud)
产生相同的结果。
其中 1 是初始累加器,如果我给它一个函数来给它一些东西来累加它会说一些有趣的东西而不是“bok”。
不过,反转这些初始值在我看来是一种奇怪的行为。我应该如何考虑 Reduce 实现?
您正在使用 Enum.reduce/2 函数。它将列表的第一个元素视为累加器。只需输入h Enum.reduce/2iex 即可。您将得到以下输出
Invokes fun for each element in the collection passing that element and the\naccumulator acc as arguments. fun's return value is stored in acc. The first\nelement of the collection is used as the initial value of acc. If you wish to\nuse another value for acc, use Enumerable.reduce/3. This function won't call\nthe specified function for enumerables that are 1-element long. Returns the\naccumulator.\n\nNote that since the first element of the enumerable is used as the initial\nvalue of the accumulator, fun will only be executed n - 1 times where n is the\nlength of the enumerable.\n\nExamples\n\n\xe2\x94\x83 iex> Enum.reduce([1, 2, 3, 4], fn(x, acc) -> x * acc end)\n\xe2\x94\x83 24\nRun Code Online (Sandbox Code Playgroud)\n\n第二段应该可以澄清你的疑问
\n\n请注意,由于可枚举的第一个元素用作累加器的初始值,因此 fun 只会执行 n - 1 次,其中 n 是可枚举的长度。
\n