【问题标题】:Immutable.js - lazy sequenceImmutable.js - 惰性序列
【发布时间】:2014-11-10 13:27:00
【问题描述】:

我最近听说了 Facebook 的 Immutable.js 库 (https://github.com/facebook/immutable-js)。我对他们的文档中的以下内容感到困惑:

var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8)
  .filter(x => x % 2).map(x => x * x);
console.log(oddSquares.last());

In this example, no intermediate arrays are ever created, filter is only called twice, and map is only called once

过滤器如何只调用两次,映射一次?

【问题讨论】:

    标签: javascript facebook lazy-evaluation lazy-sequences


    【解决方案1】:

    因为 map 和 filter 的逻辑对序列的惰性求值

    地图

    对映射序列调用的last() 返回映射器函数处理的原始序列的last()。

    例如:

     var mappedSequence = Immutable.Sequence(1,2,3,4,5,6,7,8).map(x => x * x);
     console.log(mappedSequence.last());
    

    将输出 64 并且将调用 map 仅一次,因为它所做的唯一事情就是获取原始序列 (8) 的最后一个元素并将其映射到 x => x * x (导致64)

    过滤器

    last() 在过滤后的序列上调用,将 反向遍历 序列,直到它在序列上找到符合条件的值。所以,例如

     var mappedSequence = Immutable.Sequence(1,2,3,4,5,6,7,8).filter(x => x % 2);
     console.log(mappedSequence.last());
    

    将输出 7 并且将调用过滤器只调用两次,因为它首先为 8 调用过滤器 (x => x % 2),它返回 0 表示 javascript 的 false(所以应该过滤),然后再次调用 filter 函数以使 7 % 2 = 1 对于 javascript 为 true,并将该值作为最后一个返回,而不再调用 filter 函数。

    作为帮助理解的附加示例:

     var mappedSequence = Immutable.Sequence(1,2,3,4,6,8).filter(x => x % 2);
     console.log(mappedSequence.last());
    

    会调用过滤函数四次,一次为 8(结果为假),一次为 6(再次为假),一次为 4(再次为假),最后为 3(最终为真) )

    将两部分放在一起

    你的例子:

    var oddSquares = Immutable.Sequence(1,2,3,4,5,6,7,8)
       .filter(x => x % 2).map(x => x * x);
    console.log(oddSquares.last());
    
    1. 要获取映射序列的last()值,首先要获取过滤序列的last()值
    2. 要获得过滤后序列的 last() 值,首先要获得原始序列 (8) 的 last() 值,并再次使用过滤器函数 ( x => x % 2 ) 对其进行评估,调用它第一次
    3. 由于 8 % 2 = 0,在 JS 上为假,应该被过滤,所以,我们移动到下一个值 (7) 并再次调用过滤函数用这个值
    4. 7 % 2 = 1,在JS上为真,不应该被过滤,所以,这是过滤后序列的最后一个值
    5. 我们得到了映射序列所需的最后一个值 (7),因此我们调用映射器函数 (x => x * x)仅一次得到 49,即最终结果

    最后,我们会调用过滤器函数两次,而映射器函数只调用一次

    【讨论】:

      猜你喜欢
      • 2015-08-24
      • 2016-09-19
      • 2012-03-01
      • 2011-07-21
      • 2023-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2010-12-08
      相关资源
      最近更新 更多