Clojure 将列表附加到列表序列

Clojure 将列表附加到列表序列,clojure,Clojure,我有一系列的清单: (def s '((1 2) (3 4) (5 6))) 我想在这个序列的尾部附加另一个列表,即 (concat-list s '(7 8)) => '((1 2) (3 4) (5 6) (7 8)) 各种(显然)不起作用的方法: (cons '((1 2)) '(3 4)) => (((1 2)) 3 4) (conj '(3 4) '((1 2))) => (((1 2)) 3 4) (concat '((1 2)) '(3 4)) =>

我有一系列的清单:

(def s '((1 2) (3 4) (5 6)))
我想在这个序列的尾部附加另一个列表,即

(concat-list s '(7 8))
=> '((1 2) (3 4) (5 6) (7 8))
各种(显然)不起作用的方法:

(cons '((1 2)) '(3 4))
=> (((1 2)) 3 4)

(conj '(3 4) '((1 2)))
=> (((1 2)) 3 4)

(concat '((1 2)) '(3 4))
=> ((1 2) 3 4)

;; close, but wrong order...
(conj '((1 2)) '(3 4))
=> ((3 4) (1 2))

;; Note: vectors work - do I really have to convert entire 
;; structure from lists to vectors and back again?
(conj [[1 2]] [3 4])
=> [[1 2] [3 4]]

concat list
有哪些可能的实现,或者是否存在执行此操作的库函数?

可能有更好的解决方案,但这里有一种方法:

user=> s
((1 2) (3 4) (5 6))
user=> s2
(7 8)
user=> (concat s (cons s2 '()))
((1 2) (3 4) (5 6) (7 8))

如果你发现这个集合通常是向右增长的,那么你应该把它作为一个向量开始,并保持这样。这将是最有效和方便的

但是,如果此集合主要向左生长,很少向右生长,则concat可能是您的最佳选择:

(concat '((1 2)) ['(3 4)]) (1)(2)(3)(4)) 注意,concat返回一个惰性序列,而不是一个持久列表


如果集合较大且两端频繁增长,您可能需要更高级的集合类型,如finger tree或flexvec。

作为
(cons s2'())
等于
(list s2)
,解决方案最好写成
(concat s(list s2))
@TerjeD.,谢谢,这样更好。我还没有用Clojure编写任何代码,只是为此使用了REPL.:)@特杰德。Concat仅适用于列表
(Concat'(1)'(2))=>(12)
列表提供
(列表1'(2))=>(1(2))
。Cons给出
(cons1'(2))=>(12)
,因此
Cons
是将单个元素附加到列表中的更好选择。因此,它同时适用于列表和原子。