将ISeq转换为IPersistentList

时间:2014-11-26 22:37:13

标签: clojure

问题很快就说明了:给定任何se​​q(特别是LazySeq),创建一个clojure.lang.IPersistentList维护元素顺序的实例。

我有一个解决方案,可能很明显为什么我不喜欢它:

(defn ->list
  [sq]
  (into '() (into '() sq)))

列表的问题是(into '() ...)将颠倒元素的顺序,所以我必须做两次:

(into '() [1 2 3])
;; => (3 2 1)

其他不那么冗长且更“有效”的尝试似乎无法产生clojure.lang.IPersistentList

(defn try-it
  [f]
  (let [r (f (range 10))]
    (assert (= r (range 10)))
    (class r)))

(try-it #(into '() %))   ;; => #<AssertionError ...>
(try-it seq)             ;; => clojure.lang.ChunkedCons
(try-it doall)           ;; => clojure.lang.LazySeq
(try-it #(concat '() %)) ;; => clojure.lang.LazySeq
(try-it #(concat % '())) ;; => clojure.lang.LazySeq
(try-it
  (comp 
    doall
    #(concat % '())))    ;; => clojure.lang.LazySeq

TL; DR:vec将seq转换为向量,set从它们创建集合 - Clojure列表的适当等价物是什么?

1 个答案:

答案 0 :(得分:0)

好吧,废话,如果我用时间写问题思考 - 我可能一开始就不需要答案。

(apply list (range 3))   ;; => (0 1 2)
(try-it #(apply list %)) ;; => clojure.lang.PersistentList

这似乎可以解决问题。