减少一个惰性序列,就像一个带有Clojure条件的循环 [英] Reduce a lazy sequence like a loop with a condition in Clojure

查看:284
本文介绍了减少一个惰性序列,就像一个带有Clojure条件的循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个无限的延迟序列,产生一个前导和一个模式重复,这种序列的一个简单的例子可以在Clojure中实现:

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

=> (取20无限延迟序列)
(4 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1)

我想得到一个 set 的元素组成 infinite-lazy-sequence :这是一种使用循环实现它的方法:

 code>(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 实现:

  60个1呼叫的60个样本中的60个。 
执行时间平均值:1.054975秒
执行时间std偏差:26.316442 ms
执行时间较低分位数:1.026187秒(2.5%)
执行时间上位分辨率:1.125854秒%)

@ sw1nn reduce-reduced

 案例:reduce-reduced 
评估计数:60个2次调用的60个样本中有120个。
执行时间平均值:875.091831 ms
执行时间std偏差:19.745142 ms
执行时间较低分位数:850.871606 ms(2.5%)
执行时间上位分辨率:921.947759 ms Clojure 1.5已添加

减少以允许短路减少...

 (reduce(fn [av] (av)(conj av)(reduced a)))
#{}
infinite-lazy-sequence)
=> #{1 2 3 4}


I have an infinite lazy sequence that produce a "preamble" and a "pattern repetition", a simple example of this kind of sequence could be implemented in Clojure with:

(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)

I would like to get a set of the elements forming this infinite-lazy-sequence, here is a way to implement it using loop:

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

=> #{1 2 3 4}

Here is the question: is it possible to achieve the same result using reduce? And using take-while?

Edit:

Benchmark results using clojure-1.5.1 and perforate-0.2.4

proposed loop-recur implementation:

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 implementation:

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%)

解决方案

Clojure 1.5 added reduced to allow shortcircuiting reduces...

 (reduce (fn [a v] (if-not (a v) (conj a v) (reduced a))) 
         #{} 
         infinite-lazy-sequence)
 => #{1 2 3 4}

这篇关于减少一个惰性序列,就像一个带有Clojure条件的循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆