[clojure] Clojure Core 또는 Contrib에 Zip 기능과 동등한 기능이 있습니까?

Clojure에서는 두 목록을 결합하여 쌍 목록을 제공하고 싶습니다.

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

Haskell 또는 Ruby에서는이 기능을 zip 이라고 합니다. 구현하기는 어렵지 않지만 Core 또는 Contrib에서 기능이 누락되지 않았는지 확인하고 싶었습니다.

Core 에는 zip 네임 스페이스가 있지만 Zipper 기능 기술에 대한 액세스를 제공하는 것으로 설명 되어 있지만 나중에는 그렇지 않습니다.

이런 식으로 Core에서 둘 이상의 목록을 결합하는 동등한 기능이 있습니까?

그렇지 않은 경우, 함수를 불필요하게 만드는 관용적 접근 방식이 있습니까?



답변

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

당신이 원하는 것을합니까 :

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

Haskell은 zipWith( zipWith3,, zipWith4…) 함수 모음이 필요 합니다. 왜냐하면 모두 특정 유형 이어야하기 때문입니다 . 특히, 입력 목록의 수는 고정되어야합니다. 합니다 ( zip, zip2, zip3, …은 가족의 특성화로 간주 될 수 zipWithtupling의 일반적인 사용을위한 가정).

반대로 Clojure와 다른 Lisp는 다양한 arity 기능을 잘 지원합니다. map그 중 하나이며 Haskell과 유사한 방식으로 “터플 링”에 사용될 수 있습니다.

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

Clojure에서 “튜플”을 만드는 관용적 방법은 위에 표시된 것처럼 짧은 벡터를 구성하는 것입니다.

(완전성을 위해 일부 기본 확장 기능을 가진 Haskell은 가변 arity 기능을 허용하지만 언어를 잘 이해해야하지만 바닐라 Haskell 98은 전혀 지원하지 않으므로 고정 arity 기능을 선호합니다 표준 라이브러리.)


답변

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


답변

정확히 원하는 것을 제공하기 위해 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]


답변

zipmap이라는 함수가 있는데, 비슷한 효과를 낼 수 있습니다. (zipmap (1 2 3)(4 5 6)) 출력값은 다음과 같습니다. {3 6, 2 5, 1 4}


답변

# (apply map list %)는 Python zip * 함수와 같은 행렬을 바꿉니다. 매크로 정의로 :

user => (defmacro py-zip [lst]`(지도 목록 적용 ~ lst))

# ‘사용자 / py-zip

user => (py-zip ‘((12 34 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)))

((12 34) (9 9 9 9) (5 6 7 8))