Is there an equivalent for the Zip function in Clojure Core or Contrib?

后端 未结 7 1897
野性不改
野性不改 2020-12-12 20:13

In Clojure, I want to combine two lists to give a list of pairs,

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

In Haskell or Ruby t

相关标签:
7条回答
  • 2020-12-12 20:23
    (map vector '(1 2 3) '(4 5 6))
    

    does what you want:

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

    Haskell needs a collection of zipWith (zipWith3, zipWith4, ...) functions, because they all need to be of a specific type; in particular, the number of input lists they accept needs to be fixed. (The zip, zip2, zip3, ... family can be regarded as a specialisation of the zipWith family for the common use case of tupling).

    In contrast, Clojure and other Lisps have good support for variable arity functions; map is one of them and can be used for "tupling" in a manner similar to Haskell's

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

    The idiomatic way to build a "tuple" in Clojure is to construct a short vector, as displayed above.

    (Just for completeness, note that Haskell with some basic extensions does allow variable arity functions; using them requires a good understanding of the language, though, and the vanilla Haskell 98 probably doesn't support them at all, thus fixed arity functions are preferrable for the standard library.)

    0 讨论(0)
  • 2020-12-12 20:27

    The built-in way would simply be the function 'interleave':

    (interleave [1 2 3 4] [5 6 7 8]) => [1 5 2 6 3 7 4 8]
    
    0 讨论(0)
  • 2020-12-12 20:27

    There is a function called zipmap, that may have the similar effect, (zipmap (1 2 3)(4 5 6)) The ouput is as fllows: {3 6, 2 5, 1 4}

    0 讨论(0)
  • 2020-12-12 20:31
    (map vector [1 2 3] [4 5 6])
    
    0 讨论(0)
  • 2020-12-12 20:34
    (partition 2 (interleave '(1 2 3) '(4 5 6))) 
    => ((1 4) (2 5) (3 6))
    

    or more generally

    (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))
    
    0 讨论(0)
  • 2020-12-12 20:38

    #(apply map list %) transposes a matrix just like the Python zip* function. As a macro definition:

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

    0 讨论(0)
提交回复
热议问题