nha
nha

Reputation: 18005

map-indexed function on arbitrary number of collections

There is a map-indexed function in Clojure, however (as of version "1.8.0"), it only accepts up to two arguments (source):

As I could not see any reason not to have an arbitrary number of arguments, I am trying to write my own version (reusing the existing map-indexed function) :

(defn map-index
  "like clojure.core/map-indexed but accepts more than two arguments"
  ([f] ;;(partial (map f (range))) ;; TODO transducer ?
   )
  ([f coll] (map f (range) coll))
  ([f c1 c2] (map f (range) c1 c2))
  ([f c1 c2 c3] (map f (range) c1 c2 c3))
  ([f c1 c2 c3 & colls]
   ;; Warning !
   ;; calling map-indexed with a final parameter freezes my REPL
   (map f (conj colls c3 c2 c1 (range)))))


((map-indexed list) ["a" "b" "c"])
(map-indexed list ["a" "b" "c"])

((map-index list) ["a" "b" "c"]) ;; KO

(map-index list ["a" "b" "c"])
(map-index list ["a" "b" "c"] ["d" "e" "f"]) ;; OK
(map-index list ["a" "b" "c"] ["d" "e" "f"]  ["g" "h" "i"]) ;; OK
(map-index list ["a" "b" "c"] ["d" "e" "f"]  ["g" "h" "i"] ["k" "l" "m"]) ;; freezes the REPL

How should I write this map-index function ?

Upvotes: 0

Views: 131

Answers (1)

Sam Estep
Sam Estep

Reputation: 13304

I would just write it like this:

(defn map-index
  ([f]
   (map-indexed f))
  ([f & colls]
   (apply map f (range) colls)))

Unless you really care about performance, there's no need to overcomplicate things with extra arities.

It's worth noting that since the transducer version here simply calls map-indexed, it won't work for an arbitrary number of collections. I'll leave it up to you to implement that if you need to do so.

Upvotes: 2

Related Questions