Implement counter for

I would like to iterate over the collection and at the same time maintain an ex counter

(for [x (range 10) y (inc 0)] [xy] ) 

I would like 'y' to represent a counter, so for each element, output ([0 0] [1 1] [2 2] ...). How to do it?

+6
source share
5 answers

You can use indexed from clojure.contrib.seq . Example:

 (indexed '(abcd)) => ([0 a] [1 b] [2 c] [3 d]) 

You can also use map-indexed . Example:

 (map-indexed vector "foobar") => ([0 \f] [1 \o] [2 \o] [3 \b] [4 \a] [5 \r]) 
+12
source

Use map-indexed as advised by Simeon. In the context of for it is convenient to use destructuring to get easy access to the counter and elements of the collection:

 (for [ [yx] (map-indexed vector (range 10) ) ] [xy] ) > ([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9]) 
+6
source

I suggest that if this question was still not marked as โ€œansweredโ€, there might be something else you are looking for, and perhaps this is the flexibility to define your own counter.

I agree with others that map-indexed is the way to go for the specific problem you have outlined. However, if you insist on using for , I would recommend something like this:

 (for [[xy] (map vector (range 10) (iterate inc 0))] [xy]) 

Rafal has a very similar answer, except that the counter will always start at zero and increment by 1. In my version you can define your counter as you see fit. For example, changing the above (iterate inc 0) to (iterate #(+ 2 %) 10) , instead you can have a counter that starts at 10 and increments by 2.

+2
source
 (keep-indexed (fn [i el][el i]) (range 10)) 

or

 (keep-indexed #(vec [%2 %1]) (range 10)) (keep-indexed #(identity [%2 %1]) (range 10)) ;([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9]) 
+1
source

Also remember that using indexes in Clojure is usually a smell of code.

+1
source

Source: https://habr.com/ru/post/918469/


All Articles