Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerate over a sequence in Clojure?

Tags:

In Python I can do this:

animals = ['dog', 'cat', 'bird']
for i, animal in enumerate(animals):
    print i, animal

Which outputs:

0 dog
1 cat
2 bird

How would I accomplish the same thing in Clojure? I considered using a list comprehension like this:

(println
  (let [animals ["dog" "cat" "bird"]]
    (for [i (range (count animals))
          animal animals]
      (format "%d %d\n" i animal))))

But this prints out every combination of number and animal. I'm guessing there is a simple and elegant way to do this but I'm not seeing it.

like image 980
davidscolgan Avatar asked Nov 16 '10 15:11

davidscolgan


2 Answers

There is map-indexed in core as of 1.2.

Your example would be:

(doseq [[i animal] (map-indexed vector ["dog" "cat" "bird"])]
  (println i animal))
like image 158
kotarak Avatar answered Sep 29 '22 10:09

kotarak


Quick solution:

(let [animals ["dog", "cat", "bird"]]
  (map vector (range) animals))

Or, if you want to wrap it in a function:

(defn enum [s]
  (map vector (range) s))

(doseq [[i animal] (enum ["dog", "cat", "bird"])]
  (println i animal))

What happens here is the function vector is applied to each element in both sequences, and the result is collected in a lazy collection.

Go ahead, try it in your repl.

like image 42
Leonel Avatar answered Sep 29 '22 11:09

Leonel