web-dev-qa-db-ja.com

Clojure CoreまたはContribにZip関数に相当するものはありますか?

Clojureでは、2つのリストを組み合わせてペアのリストを作成し、

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

HaskellまたはRuby関数はZipと呼ばれます。実装は難しくありませんが、 CoreまたはContribの関数が欠落していませんでした。

Coreには Zip 名前空間がありますが、Zipper機能テクニックへのアクセスを提供する 記述 です。

このようにCoreで2つ以上のリストを結合するための同等の機能はありますか?

ない場合は、関数を不要にする慣用的なアプローチがあるためでしょうか?

117
John Kane
(map vector '(1 2 3) '(4 5 6))

あなたがしたいことをします:

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

HaskellにはzipWithzipWith3zipWith4、...)関数。すべて特定のtype;である必要があるため特に、受け入れる入力リストの数を修正する必要があります。 (ZipZip2Zip3、...ファミリは、タプルの一般的なユースケースのzipWithファミリの特殊化と見なすことができます)。

対照的に、Clojureと他のLispは、可変アリティ関数を適切にサポートしています。 mapはそれらの1つであり、Haskellの方法に似た方法で「タプリング」に使用できます。

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

Clojureで「タプル」を構築する慣用的な方法は、上記のように短いベクターを構築することです。

(完全を期すために、いくつかの基本的な拡張機能を備えたHaskellは可変アリティ関数を許可することに注意してください。ただし、それらを使用するには言語の十分な理解が必要であり、Vanilla Haskell 98はおそらくそれらをまったくサポートしていないため、固定アリティ関数が望ましいです標準ライブラリ用。)

204
Michał Marczyk
(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))
16
Lambder
(map vector [1 2 3] [4 5 6])
12
danlei

必要なものを正確に提供するために、2つのリスト間でlistをマッピングすると、例のようなリストのリストが得られます。多くのClojuriansは、これにベクトルを使用する傾向があると思いますが、それは何でも動作します。また、入力は同じタイプである必要はありません。 mapはそれらからseqを作成し、seqをマッピングして、seq'able入力が正常に機能するようにします。

(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))
10
Arthur Ulfeldt

組み込みの方法は、単に関数 'interleave'になります。

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