代码之家  ›  专栏  ›  技术社区  ›  Kannan Ramamoorthy

Clojure-使第一个+过滤器懒惰

  •  3
  • Kannan Ramamoorthy  · 技术社区  · 6 年前

    first + filter . 我注意到过滤器对所有输入都不必要地运行。 滤波器 懒散地运行,以便它不必对整个输入应用谓词。

    (defn filter-even
      [n]
      (println n)
      (= (mod n 2) 0))
    
    (first (filter filter-even (range 1 4)))
    

    上面的代码打印出来

    1

    2 . 我们怎样才能让它变懒呢?

    1 回复  |  直到 4 年前
        1
  •  10
  •   Carcigenicate    6 年前

    这是因为 range 是一个分块序列:

    (chunked-seq? (range 1))
    => true
    

    (first (filter filter-even (range 1 100)))
    1
    2
    . . .
    30
    31
    32
    => 2
    

    This overview 显示 unchunk

    (defn unchunk [s]
      (when (seq s)
        (lazy-seq
          (cons (first s)
                (unchunk (next s))))))
    
    (first (filter filter-even (unchunk (range 1 100))))
    2
    => 2
    

    或者,你可以申请 list 因为列表不是分块的:

    (first (filter filter-even (apply list (range 1 100))))
    2
    => 2
    

    但是很明显,整个集合需要实现预过滤。

    老实说,这不是我一直担心的事情。过滤功能通常不是 很贵,32个元素的块不是 那个 在事情的大计划中。