Mic*_*ent 52 collections clojure
我发现自己做了很多:
(concat coll [e])
其中coll是一个集合,而ea是一个单独的元素.
在Clojure中有没有这样做的功能?我知道conj对矢量做的最好,但我不知道前面会使用哪种coll.例如,它可以是矢量,列表或排序集.
ama*_*loy 53
某些类型的集合可以廉价地添加到前面(列表,seq),而其他类型的集合可以廉价地添加到后面(向量,队列,有点类型lazy-seqs).如果可能的话,你应该安排使用其中一种类型(向量是最常见的)而不是使用concat,而只需要使用它:(conj [1 2 3] 4)
收益率[1 2 3 4]
,而(conj '(1 2 3) 4)
收益率(4 1 2 3)
.
Lau*_*tit 14
concat不会在集合的尾部添加元素,也不会连接两个集合.
concat返回由两个其他seq的串联组成的seq.对于concat的返回类型,可以推断出可以推断seq的集合的原始类型.
现在,Clojure的集合都为了写出高效的代码不同的属性必须知道,这就是为什么没有在核心提供的通用功能来连接任何类型的集合在一起.相反,列表和向量确实具有"自然插入位置",它们知道并且做出适合于该类型集合的内容.
这是@ amalloy答案的一个非常小的附录,以解决OP对一个函数的要求,该函数总是增加任何类型集合的尾部.这是另一种选择(concat coll [x])
.只需创建原始集合的矢量版本:
(defn conj*
[s x]
(conj (vec s) x))
Run Code Online (Sandbox Code Playgroud)
注意事项:
如果你以一个懒惰的序列开始,你现在已经破坏了懒惰 - 即输出不是懒惰的.根据您的需要,这可能是好事还是坏事.
创建矢量需要一些成本.如果你需要经常调用这个函数,并且你发现(例如通过使用Criterium进行基准测试)这个成本对于你的目的很重要,那么请按照其他答案的建议尝试首先使用向量.
要充分利用amalloy和Laurent Petit所说的话,请使用该conj
函数。
Clojure提供的出色抽象之一是Sequence API,其中包括该conj
函数。如果可能的话,您的代码应尽可能与集合类型无关,而应使用seq API处理集合的操作,并仅在需要特定时才选择特定的集合类型。
如果矢量是很好的匹配,那么可以,conj
将在最后添加项目。如果使用列表代替,那么conj
会将东西添加到集合的前面。但是,如果您随后使用标准的seq API函数从集合的“顶部”(向量的背面,列表的正面)提取项目,则使用哪种实现都无关紧要,因为它将始终使用具有最佳性能并因此添加和删除项目的项目将保持一致。
归档时间: |
|
查看次数: |
42626 次 |
最近记录: |