在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需要zipWith
( zipWith3
, zipWith4
,…)函数的集合,因为它们都需要是特定的types ; 特别是他们接受的input表的数量需要加以修正。 ( zip
, zip3
, zip3
,…系列可以看作是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}