Clojure 如何创建一个以随机顺序重复另一个集合元素的惰性seq?

Clojure 如何创建一个以随机顺序重复另一个集合元素的惰性seq?,clojure,lazy-sequences,Clojure,Lazy Sequences,我想创建一个惰性序列,重复来自另一个集合的元素。它应该在重复之前生成每个元素中的一个。元素的顺序必须是随机的 它的行为应该是这样的: =>(拍摄10倍) (B A C B A C A B C) 这似乎有效: (def x(lazy seq(concat(lazy seq(shuffle['A'B'C]))x))) 但是,它使用了两个惰性seq。有没有一种方法可以只使用一个lazy seq来编写这种惰性序列 如果不能用一个惰性seq完成,那么如何生成值?因为我的集合只有三个项,所以我希望在第一

我想创建一个惰性序列,重复来自另一个集合的元素。它应该在重复之前生成每个元素中的一个。元素的顺序必须是随机的

它的行为应该是这样的:

=>(拍摄10倍)
(B A C B A C A B C)
这似乎有效:

(def x(lazy seq(concat(lazy seq(shuffle['A'B'C]))x)))
但是,它使用了两个
惰性seq
。有没有一种方法可以只使用一个
lazy seq
来编写这种惰性序列

如果不能用一个
惰性seq
完成,那么如何生成值?因为我的集合只有三个项,所以我希望在第一个块中完全计算内部的lazy seq

在想出上面的顺序之前,我尝试了下面的一个:

=>(def x(lazy seq(concat(shuffle['A'B'C])x)))
=>(取10倍)
(C A B C A B C A B C)

我希望您能解释一下为什么这一个不会随机分配每个批次。

重复序列,然后使用shuffle函数对其进行映射怎么样?以下是一个例子:

(take 10 (mapcat shuffle (repeat ['A 'B 'C])))
;=> (B C A B A C B A C B)

重复这个序列,然后用shuffle函数映射它,怎么样?以下是一个例子:

(take 10 (mapcat shuffle (repeat ['A 'B 'C])))
;=> (B C A B A C B A C B)
我希望你能解释一下为什么这一个不能随机分配每一批

你的
(shuffle'[abc])
只被计算一次,当序列开始时,被洗牌的列表被反复使用

下面是一个小测试:

user> (defn test-fnc [coll]
        (do (print "boom!")
            (shuffle coll)))
;; => #'user/test-fnc
user> (def x (lazy-seq (concat (test-fnc '[a b c]) x)))
;; => #'user/x
user> (take 10 x)
;; => (boom!b c a b c a b c a b)
user> (take 10 x)
;; => (b c a b c a b c a b)
您也可以改为使用:

但这并不能解决您的问题:-)

这是因为:

获取返回
ISeq
nil
的表达式体,并生成一个Seqable对象,该对象将仅在第一次调用seq时调用该体,并将缓存结果并在所有后续seq调用时返回该结果


如果根据函数调用重写定义:

(defn x [] (lazy-seq (concat (shuffle ['A 'B 'C]) (x))))
它将在以下方面发挥作用:

user> (take 10 (x))
;; => (C B A C A B B A C B)
因为每次调用都会有不同的惰性seq,而不是重复自身的相同缓存seq

我希望你能解释一下为什么这一个不能随机分配每一批

你的
(shuffle'[abc])
只被计算一次,当序列开始时,被洗牌的列表被反复使用

下面是一个小测试:

user> (defn test-fnc [coll]
        (do (print "boom!")
            (shuffle coll)))
;; => #'user/test-fnc
user> (def x (lazy-seq (concat (test-fnc '[a b c]) x)))
;; => #'user/x
user> (take 10 x)
;; => (boom!b c a b c a b c a b)
user> (take 10 x)
;; => (b c a b c a b c a b)
您也可以改为使用:

但这并不能解决您的问题:-)

这是因为:

获取返回
ISeq
nil
的表达式体,并生成一个Seqable对象,该对象将仅在第一次调用seq时调用该体,并将缓存结果并在所有后续seq调用时返回该结果


如果根据函数调用重写定义:

(defn x [] (lazy-seq (concat (shuffle ['A 'B 'C]) (x))))
它将在以下方面发挥作用:

user> (take 10 (x))
;; => (C B A C A B B A C B)

因为每次调用都会有不同的惰性seq,而不是重复的相同缓存seq。

谢谢您的详细回答。我不知道为什么被否决了。您的解决方案使用了一个函数,这对我来说并不理想,但它确实揭示了缓存的根本问题。这对我来说是一个RTFM问题,我并不感到惊讶。但我已经发布了这篇文章,希望它也能造福于其他人。@muhuk,嗯,我看不出它被否决了,对我来说,它的得分是:1上0下。它们在创建时不是
1
?(我可能与其他服务混淆了。Nvm me。)谢谢您的详细回答。我不知道为什么被否决了。您的解决方案使用了一个函数,这对我来说并不理想,但它确实揭示了缓存的根本问题。这对我来说是一个RTFM问题,我并不感到惊讶。但我已经发布了这篇文章,希望它也能造福于其他人。@muhuk,嗯,我看不出它被否决了,对我来说,它的得分是:1上0下。它们在创建时不是
1
?(我可能与其他服务混淆了。请告诉我。)