How to find length of lazy sequence without forcing realization?

后端 未结 2 1805
鱼传尺愫
鱼传尺愫 2021-01-18 01:16

I\'m currently reading the O\'reilly Clojure programming book which it\'s says the following in it\'s section about lazy sequences:

It is possible (th

2条回答
  •  野的像风
    2021-01-18 01:31

    As inspired by soulcheck's answer, here is a lazy but counted map of an expensive function over a fixed size collection.

    (defn foo [s f] 
      (let [c (count s), res (map f s)] 
        (reify 
          clojure.lang.ISeq 
            (seq [_] res) 
          clojure.lang.Counted 
            (count [_] c) 
          clojure.lang.IPending 
            (isRealized [_] (realized? res)))))
    
    
    (def bar (foo (range 5) (fn [x] (Thread/sleep 1000) (inc x))))
    
    (time (count bar))
    ;=> "Elapsed time: 0.016848 msecs"
    ;    5
    
    (realized? bar)
    ;=> false
    
    
    (time (into [] bar))
    ;=> "Elapsed time: 4996.398302 msecs"
    ;   [1 2 3 4 5]
    
    (realized? bar)
    ;=> true
    
    (time (into [] bar))
    ;=> "Elapsed time: 0.042735 msecs"
    ;   [1 2 3 4 5]
    

提交回复
热议问题