(defn my-zipmap [keys vals]
(loop [my-map {}
my-keys (seq keys)
my-vals (seq vals)]
(if (and my-keys my-vals)
(recur (assoc my-map (first my-keys) (first my-vals))
(rest my-keys)
(rest my-vals))
my-map)))
The example needs to be updated for the lazier seqs that were
implemented before the Clojure 1.0 release. As part of that change, we
lost "nil punning". "rest" no longer returns nil if there are no more
items. A new function "next" does though:
user=> (source zipmap)
(defn zipmap
"Returns a map with the keys mapped to the corresponding vals."
[keys vals]
(loop [map {}
ks (seq keys)
vs (seq vals)]
(if (and ks vs)
(recur (assoc map (first ks) (first vs))
(next ks)
(next vs))
map)))
nil
user=> (doc rest)
-------------------------
clojure.core/rest
([coll])
Returns a possibly empty seq of the items after the first. Calls
seq on its
argument.
nil
user=> (doc next)
-------------------------
clojure.core/next
([coll])
Returns a seq of the items after the first. Calls seq on its
argument. If there are no more items, returns nil.
nil
This is the example that needs updating at clojure.org:
http://clojure.org/functional_programming#toc7
--Steve
Yes, this (Steve's) version, using next and testing directly with (and
ks vs) is the idiomatic way when you are not in turn producing a lazy
seq.
(if-not (or (empty? ks) (empty? vs))
is to be avoided. (No offense Cosmin :)
Rich