在Clojure Core或Contrib中有Zip函数的等价物吗?

在Clojure中,我想结合两个列表给出一个对列表,

> (zip '(1 2 3) '(4 5 6)) ((1 4) (2 5) (3 6)) 

在Haskell或Ruby中,函数被称为zip 。 实现它并不困难,但我想确保在Core或Contrib中不会缺less函数。

Core中有一个zip命名空间,但它被描述为提供对Zipperfunction技术的访问,这看起来并不是我所追求的。

是否有一个相同的function,结合2个或更多的列表,这样,在核心?

如果没有,是不是因为有一种惯用的方法使得这个function不需要呢?

 (map vector '(1 2 3) '(4 5 6)) 

做你想要的:

 => ([1 4] [2 5] [3 6]) 

Haskell需要zipWithzipWith3zipWith4 ,…)函数的集合,因为它们都需要是特定的types ; 特别是他们接受的input表的数量需要加以修正。 ( zipzip3zip3 ,…系列可以看作是zipWith系列的常见用例)。

相比之下,Clojure和其他Lisp对variables函数有很好的支持。 map就是其中之一,可以用类似于Haskell的方式来“捣蛋”

 zipWith (\xy -> (x, y)) 

在Clojure中构build一个“元组”的惯用方法是构造一个短vector,如上所示。

(为了完整起见,注意Haskell有一些基本的扩展允许variablesarity函数,但是使用它们需要对语言有很好的理解,而且Haskell 98可能根本不支持它们,所以固定的arity函数是可以select的为标准库。)

 (map vector [1 2 3] [4 5 6]) 
 (partition 2 (interleave '(1 2 3) '(4 5 6))) => ((1 4) (2 5) (3 6)) 

或更一般地说

 (defn zip [& colls] (partition (count colls) (apply interleave colls))) (zip '( 1 2 3) '(4 5 6)) ;=> ((1 4) (2 5) (3 6)) (zip '( 1 2 3) '(4 5 6) '(2 4 8)) ;=> ((1 4 2) (2 5 4) (3 6 8)) 

为了准确地给你想要的东西,在这两个列表中的映射list会给你列表的列表,就像你的例子。 我认为很多Clojurians倾向于使用vector,尽pipe它可以与任何东西一起工作。 而且input不需要是相同的types。 地图从他们创buildseqs,然后映射seqs,所以任何seq'ableinput将正常工作。

 (map list '(1 2 3) '(4 5 6)) (map list [1 2 3] '(4 5 6)) (map hash-map '(1 2 3) '(4 5 6)) (map hash-set '(1 2 3) '(4 5 6)) 

内置的方式只是“交错”function:

 (interleave [1 2 3 4] [5 6 7 8]) => [1 5 2 6 3 7 4 8] 

#(应用地图列表%)像Python的zip *函数一样转换一个matrix。 作为macros定义:

user =>(defmacro py-zip [lst]`(apply map list〜lst))

#'用户/ PY-拉链

用户=>(py-zip'((1 2 3 4)(9 9 9 9)(5 6 7 8)))

((1 9 5)(2 9 6)(3 9 7)(4 9 8))

用户=>(py-zip'((1 9 5)(2 9 6)(3 9 7)(4 9 8)))

((1 2 3 4)(9 9 9 9)(5 6 7 8))

有一个称为zipmap的函数,可能会有类似的效果,(zipmap (1 2 3) (4 5 6))输出如下:{3 6,2 5,1 4}