【问题标题】:List.foldr or List.foldl understanding with Elixir用 Elixir 理解 List.foldr 或 List.foldl
【发布时间】:2017-09-08 22:48:51
【问题描述】:

我正在阅读 Elixir 文档,并且遇到了 Elixir List 模块的“foldr”功能。我真的很难理解它。这是文档所说的:

文档

Folds (reduces) the given list from the right with a function. Requires an accumulator.

iex> List.foldr([1, 2, 3, 4], 0, fn(x, acc) -> x - acc end)
-2

所以这应该返回 -2。但是当我阅读它时,我似乎认为它每次都试图将一个数字减0,如果是这样,我们如何得到-2?我显然不了解蓄能器,有人可以帮我分解一下吗?

【问题讨论】:

    标签: elixir


    【解决方案1】:

    了解此类函数如何工作的最简单方法是使用带有所有参数的 IO.puts 调用。

    iex(1)> List.foldr([1, 2, 3, 4], 0, fn(x, acc) -> IO.puts "#{x} - #{acc} = #{x - acc}"; x - acc end)
    4 - 0 = 4
    3 - 4 = -1
    2 - -1 = 3
    1 - 3 = -2
    -2
    

    所以,在第一次迭代中,x 为 4,acc 为 0,我们得到x - acc = 4 - 0 = 4。最后我们得到了-2

    【讨论】:

      【解决方案2】:

      使用函数从右侧折叠(减少)给定列表。需要一个蓄能器。

      这意味着列表是从右侧迭代的,例如。 G。传递的函数按以下顺序调用 4 次:

      fn(4, 0) -> 4 - 0 end
      fn(3, 4) -> 3 - 4 end
      fn(2, -1) -> 2 + 1 end
      fn(1, 3) -> 1 - 3 end
      

      因此,返回-2

      【讨论】:

        【解决方案3】:

        虽然已经给出的两个答案都完美地回答了这个问题,但我会为那些来自 OOP 背景的人提出自己的答案:

        List.foldr/3List.foldl/3 都是简单的减速器。在伪代码中(为了清楚起见,我们选择),List.foldl/3 完全等同于:

        [1, 2, 3, 4].reduce(0) { |acc, x| x - acc }
        #⇒ 2
        

        List.foldr/3 以 RtL 顺序接受参数,因此我们应该提前反转一个列表:

        [1, 2, 3, 4].reverse.reduce(0) { |acc, x| x - acc }
        #⇒ -2
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-12-14
          • 2017-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多