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つ以上のリストを結合するための同等の機能はありますか?
ない場合は、関数を不要にする慣用的なアプローチがあるためでしょうか?
(map vector '(1 2 3) '(4 5 6))
あなたがしたいことをします:
=> ([1 4] [2 5] [3 6])
HaskellにはzipWith
(zipWith3
、zipWith4
、...)関数。すべて特定のtype;である必要があるため特に、受け入れる入力リストの数を修正する必要があります。 (Zip
、Zip2
、Zip3
、...ファミリは、タプルの一般的なユースケースのzipWith
ファミリの特殊化と見なすことができます)。
対照的に、Clojureと他のLispは、可変アリティ関数を適切にサポートしています。 map
はそれらの1つであり、Haskellの方法に似た方法で「タプリング」に使用できます。
zipWith (\x y -> (x, y))
Clojureで「タプル」を構築する慣用的な方法は、上記のように短いベクターを構築することです。
(完全を期すために、いくつかの基本的な拡張機能を備えたHaskellは可変アリティ関数を許可することに注意してください。ただし、それらを使用するには言語の十分な理解が必要であり、Vanilla Haskell 98はおそらくそれらをまったくサポートしていないため、固定アリティ関数が望ましいです標準ライブラリ用。)
(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))
(map vector [1 2 3] [4 5 6])
必要なものを正確に提供するために、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))
組み込みの方法は、単に関数 'interleave'になります。
(interleave [1 2 3 4] [5 6 7 8]) => [1 5 2 6 3 7 4 8]