Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在clojure中合并两个序列?_Clojure_Sequences - Fatal编程技术网

如何在clojure中合并两个序列?

如何在clojure中合并两个序列?,clojure,sequences,Clojure,Sequences,Clojure中合并(或检索)两个列表(或序列)的惯用方法是什么 (merge l1 l2) 似乎不是解决方案: a=> (merge '(1 2 3) '(2 3 4)) ((2 3 4) 1 2 3) 获得两个列表并集的一种方法是使用union Clojure> (into #{} (clojure.set/union '(1,2,3) '(3,4,5))) #{1 2 3 4 5} 或者如果你想得到一份清单 (into '() (into #{} (clojure.set

Clojure中合并(或检索)两个列表(或序列)的惯用方法是什么

(merge l1 l2)
似乎不是解决方案:

a=> (merge '(1 2 3) '(2 3 4))
((2 3 4) 1 2 3)

获得两个列表并集的一种方法是使用
union

Clojure> (into #{} (clojure.set/union '(1,2,3) '(3,4,5)))
#{1 2 3 4 5}
或者如果你想得到一份清单

(into '() (into #{} (clojure.set/union '(1,2,3) '(3,4,5))))
(5 4 3 2 1)

我认为安迪的解决方案非常有效。这里有另一种方法,因为嘿,为什么不呢。它使用和:


如果您想要的实际上是不同的未排序数据(集合),那么应该使用Clojure的集合数据结构,而不是向量或列表。正如andih间接指出的,有一个集合操作的核心库:

如果出于任何原因,集合不是您想要的,那么请继续阅读。当你的序列中有大量的数据时,请小心使用<代码> CONTAG/COD>,并考虑使用<代码>到。我不知道为什么concat没有使用into实现(或者更好——为什么concat甚至存在?顺便说一句,虽然into比concat快得多,但它仍然比conj慢得多。Bagwell的RRB树,与Clojure和Scala兼容,将解决这个问题,但还没有为Clojure实现)

将Omri的非集合解决方案重新表述为“进入”:

(distinct (into [1 2 3] [3 4 5]))
=> (1 2 3 4 5)

如果您不介意复制,您可以尝试:

一种选择是:

需要注意的一点是,它将扁平化嵌套较深的集合:

(flatten [[1 2 [3 4 5]] [1 [2 [3 4]]]]) ;; => (1 2 3 4 5 1 2 3 4)
但对于地图来说效果很好:

(flatten [[{} {} {}] [{} {} {}]]) ;; => ({} {} {} {} {} {})

你如何定义“合并”?e、 g.是否存在重复项,如果存在,如何处理重复项?另外,您是否知道列表是否已排序?仅供参考。函数名
merge
,已被
clojure.core
采用。为避免混淆,您可以为
merge
函数选择其他名称。请看,海报实际上使用的是clojure.core/merge,但不是在哈希映射或其他关联数据上,并且所述函数在该上下文中具有未定义的行为。(->{}(into[1 2 3])(into[3 4 5])seq)使用
union
对列表参数进行操作时,您并没有真正实现任何功能。它所做的只是
(reduce conj'(1,2,3)'(3,4,5))
clojure.set
函数被设计为与set参数一起工作。出于性能原因,我建议不要使用concat,因为它速度惊人地慢。请参阅下面我的答案以进行进一步讨论。@rplevy感谢您的评论(以及下面的答案)。我没有意识到concat有性能问题。concat有什么不好的?它是常数时间,因为它是懒惰的,而不是严格语言中的线性时间实现?它是使用conj实现的
(进入foo-bar)
(reduce conj-foo-bar)
相同,只是它会使用瞬变,如果它们可用的话。不,我说conj更快!(但如果你需要连接向量,而不仅仅是将一个向量连接到另一个向量上,这些是不同的需要。)菲利普:into使用瞬变,非常类似于《Clojure的欢乐》中的向量连接瞬变示例,事实上,这是一个寻找更多讨论的好地方。@pete很抱歉回答晚了
concat
是懒惰的,所以它可以是常数时间,因为它实际上不做很多工作。它返回的内容在作为seq使用时,首先从第一个arg获取项目,然后在第一个arg耗尽时从第二个arg获取项目。
(concat '(1 2 3 ) '(4 5 6 1) '(2 3)) 
;;==> (1 2 3 4 5 6 1 2 3) 
(def colls '((1 2 3) (2 3 4)))
(flatten colls) ;; => (1 2 3 2 3 4)
(distinct (flatten colls)) ;; => (1 2 3 4)
(flatten [[1 2 [3 4 5]] [1 [2 [3 4]]]]) ;; => (1 2 3 4 5 1 2 3 4)
(flatten [[{} {} {}] [{} {} {}]]) ;; => ({} {} {} {} {} {})