将元素放到集合的尾部

我发现自己做了很多:

(concat coll [e])其中,coll是一个集合,是单个元素。

在Clojure中有这个function吗? 我知道conj做vector的工作最好,但我不知道前面哪个coll将被使用。 例如,它可能是一个向量,列表或sorting集。

某些types的集合可以便宜地添加到前面(列表,seq),而其他types可以便宜地添加到后面(向量,队列,类似于lazy-seqs)。 如果可能的话,你应该安排使用其中的一种types(向量是最常见的),而只是连接它: (conj [1 2 3] 4)产生[1 2 3 4] ,而(conj '(1 2 3) 4)产生(4 1 2 3)

concat不会将元素添加到集合的尾部,也不会连接两个集合。

concat返回一个由另外两个seq组成的seq。 可以推断seqs的集合的原始types会因为concat的返回types而丢失。

现在,为了编写高效的代码,clojure集合具有不同的属性,这就是为什么在核心中没有可用的通用函数来将任何types的集合连接在一起。 相反,列表和向量确实具有共同知道的“自然插入位置”,并且对于这种集合是正确的。

提炼amalloy和Laurent Petit已经说过的最好的东西: 使用conj函数

Clojure提供的一个伟大的抽象是Sequence API,它包含了conj函数。 如果可能的话,你的代码应该像集合types一样不可知,而是使用seq API来处理集合上的操作,并且只在需要特定时才select特定的集合types。

如果向量是一个很好的匹配,那么是的,连接将添加项目结束。 如果使用列表,那么conj将会把东西添加到你的集合的前面。 但是,如果您使用标准的seq API函数从集合的“顶部”(向量的后面,列表的前面)拉取项目,则使用哪个实现并不重要,因为它将始终使用性能最好的一个,因此增加和删除项目将是一致的。

这是@ amalloy答案的一个非常小的附录,以解决OP对函数的请求,这个函数总是会增加任何types的集合的尾部。 这是(concat coll [x])的替代方法。 只需创build原始集合的vector版本即可:

 (defn conj* [sx] (conj (vec s) x)) 

注意事项:

如果你开始一个懒惰的序列,你现在已经摧毁了懒惰 – 即输出不是懒惰的。 这可能是一件好事,也可能是一件坏事,这取决于你的需求。

创buildvector有一些成本。 如果您需要调用这个函数,并且您发现(例如通过与Criterium进行基准testing),那么这个代价对于您的目标是非常重要的,那么请遵循其他答案的build议来尝试首先使用向量。