【问题标题】:Elixir reduce order of elementsElixir减少元素的顺序
【发布时间】:2016-02-18 09:30:06
【问题描述】:

为了了解 Elixir 如何执行 Enum.reduce,我将其插入 put 以观察输出。我不清楚为什么它首先执行第二个列表元素,而不是第一个,然后独立地遍历所有其他元素。

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 实施?

【问题讨论】:

标签: elixir reduce


【解决方案1】:

您正在使用 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

第二段应该澄清你的疑问

注意,由于枚举的第一个元素被用作初始 累加器的值, fun 只会执行 n - 1 次,其中 n 是 可枚举的长度。

【讨论】:

  • 谢谢。这个问题源于试图弄清楚 &2 引用了什么(最初认为它是该系列中的第二个元素)。现在我知道它是累加器。
  • 如果这对您有所帮助,请点赞。如果您认为这是合适的答案,请将其标记为答案。
  • 确认。我在这个 stackoverflow 社区中没有足够的影响力来显示我的赞成票(还)。现在我神奇地做到了:)
  • 当然,没问题。总有一天我们都是初学者。一旦您拥有权利,请投票。
【解决方案2】:

Enum.reduce 有两个函数,Enum.reduce/2Enum.reduce/3Enum.reduce/3 是常用的 reduce 函数,采用可枚举的初始累加器和归约函数。 Enum.reduce/2/3 非常相似,但跳过了初始累加器,而是将可枚举中的第一个元素作为累加器,对于列表,它可以实现为:def reduce([first|rest], fun), do: reduce(rest, first, fun)

【讨论】:

  • 谢谢!我对使用累加器为 0 的 Enum.reduce/3 有一点启发,它以正确的顺序显示元素: Enum.reduce([1,2,3,4], 1, &(IO.puts( "a#{&1} b#{&2}")))
猜你喜欢
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 2021-01-02
  • 2015-12-25
相关资源
最近更新 更多