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


130

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

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

HaskellまたはRubyでは、この関数はzipと呼ばれます。実装は難しくありませんが、CoreやContribの関数を見逃さないようにしたかったのです。

Coreにはzip名前空間がありますが、それはZipper機能技術へのアクセスを提供するものとして説明されていますが、私が求めているようには見えません。

このようにコアで2つ以上のリストを組み合わせるための同等の関数はありますか?

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


zipTupeloライブラリには関数があります: cloojure.github.io/doc/tupelo/tupelo.core.html#var-zip
Alan Thompson

回答:


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

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

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

Haskellはのコレクションを必要とするzipWithzipWith3zipWith4、...)機能、彼らはすべての必要性は、特定のであるとするのでタイプ。特に、それらが受け入れる入力リストの数は固定する必要があります。(zipzip2zip3、...家族は、専門とみなすことができるzipWithtuplingの一般的な使用の場合の家族)。

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

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

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

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


8
これはzip、コレクションが同じ長さでない場合とは動作が異なることに注意してください。Rubyは処理を続行nilし、短いコレクションのを提供しますが、Clojureはコレクションの1つが使い果たされると処理を停止します。
ネイトW.

@NateW。感謝します、ありがとう。Haskell では、この点でzipClojureのように動作しmapます。
のMichałMarczyk

1
可変アリティHaskell関数のリファレンスをお願いしてもよいですか?
テオドール2018

22
(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))


11

list2つのリストをマッピングすると、例のようにリストのリストが表示されます。多くのClojuriansは、何でも機能しますが、ベクトルを使用する傾向があると思います。また、入力は同じタイプである必要はありません。mapはそれらからシーケンスを作成し、次にシーケンスをマッピングするので、シーケンス可能な入力はすべて正常に機能します。

(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))

1
マップとセットではなく、ハッシュマップとハッシュセットを意味していると思います。
cgrand 2010

3

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

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

6
OPの目標を達成するには、追加する必要があります(partition 2 (interleave [1 2 3 4][5 6 7 8]))
skuro

はい-私はOPの望ましい出力をあまり詳しく見ていないようです。
lsh 2012年

-1

同様の効果をもたらす可能性のあるzipmapと呼ばれる関数があります(zipmap (1 2 3)(4 5 6))出力は次のとおりです:{3 6、2 5、1 4}


zipmapはマップを返しますが、これは順序を保証するものではありません
イリヤ

-2

#(apply map list%)は、Pythonのzip *関数と同じように行列を転置します。マクロ定義として:

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

# 'user / py-zip

user =>(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))

user =>(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))


これは単に「マップ」を使用するよりも優れていますか?そして、ここでマクロのポイントは何ですか?
デイブニュートン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.