2

「プリアンブル」と「パターンの繰り返し」を生成する無限のレイジーシーケンスがあります。この種のシーケンスの簡単な例は、Clojureで次のように実装できます。

(def infinite-lazy-sequence
  (lazy-cat [4] (cycle [1 2 3])))

=> (take 20 infinite-lazy-sequence)
(4 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1)

setこれを形成する要素を取得したいのinfinite-lazy-sequenceですが、これを使用して実装する方法は次のloopとおりです。

(loop
  [[head & tail] infinite-lazy-sequence
   result #{}]
  (if (contains? result head)
    result
    (recur tail (conj result head))))

=> #{1 2 3 4}

ここに質問があります:使用して同じ結果を達成することは可能reduceですか?そして、使用してtake-whileいますか?

編集:

clojure-1.5.1とperforate-0.2.4を使用したベンチマーク結果

提案されたloop-recur実装:

Case:  :loop-recur
Evaluation count : 60 in 60 samples of 1 calls.
             Execution time mean : 1.054975 sec
    Execution time std-deviation : 26.316442 ms
   Execution time lower quantile : 1.026187 sec ( 2.5%)
   Execution time upper quantile : 1.125854 sec (97.5%)

@ sw1nnのreduce-reduced実装:

Case:  :reduce-reduced
Evaluation count : 120 in 60 samples of 2 calls.
             Execution time mean : 875.091831 ms
    Execution time std-deviation : 19.745142 ms
   Execution time lower quantile : 850.871606 ms ( 2.5%)
   Execution time upper quantile : 921.947759 ms (97.5%)
4

1 に答える 1

4

短絡を減らすためにClojure1.5が追加されましreducedた...

 (reduce (fn [a v] (if-not (a v) (conj a v) (reduced a))) 
         #{} 
         infinite-lazy-sequence)
 => #{1 2 3 4}
于 2013-03-25T22:05:50.850 に答える