【问题标题】:How to create a lazy-seq that repeats elements of another collection, in random order?如何创建一个以随机顺序重复另一个集合的元素的惰性序列?
【发布时间】:2014-10-12 06:26:26
【问题描述】:

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

它的行为应该是这样的:

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

这似乎有效:

(def x (lazy-seq (concat (lazy-seq (shuffle ['A 'B 'C])) x)))

但是它使用了两个lazy-seq。有没有办法只使用一个lazy-seq 来编写这种惰性序列?

如果用一个lazy-seq 无法做到这一点,如何生成值?由于我的集合只有三个项目,我希望在第一个块中完全计算内部惰性序列。

在提出上述顺序之前,我尝试了以下顺序:

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

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

我将不胜感激任何解释为什么这个不随机化每批。

【问题讨论】:

    标签: clojure lazy-sequences


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我将不胜感激任何解释为什么这个不随机化每批。

      你的(shuffle '[a b c]) 只被评估一次,当序列的开始被实现时,就会一次又一次地使用打乱列表。

      这是一个小测试:

      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)
      

      您也可以改用lazy-cat

      user> (def x (lazy-cat (shuffle '[a b c]) x))
      ;; => #'user/x
      

      但不会解决你的问题:-)

      这是因为lazy-seq:

      获取返回ISeqnil的表达式主体,并生成一个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)
      

      因为每次调用都会有不同的惰性序列,而不是重复自身的同一个缓存序列。

      【讨论】:

      • 感谢您的详细回答。我不知道为什么它被否决了。您的解决方案使用了一个函数,这对我来说并不理想,但它确实为缓存的潜在问题提供了一些启示。我并不惊讶这对我来说是一个 RTFM 问题。但我已经发布了这篇文章,希望它也能造福其他人。
      • @muhuk,嗯,我没有看到它被否决,对我来说它的得分:1 上和 0 下..
      • 创建时不是1吗? (我可能对其他一些服务感到困惑。Nvm me。)
      猜你喜欢
      • 2013-11-28
      • 1970-01-01
      • 2016-02-23
      • 1970-01-01
      • 2018-11-19
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 2020-07-15
      相关资源
      最近更新 更多