2012-06-19 17 views
6

me gustaría iterar sobre una colección y al mismo tiempo también mantener un contador de exLa implementación de un contador en para

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

me gustaría 'y' para representar el contador, por lo que para cada elemento de la salida es ([0 0] [1 1] [2 2] ...). ¿Cómo puedo hacer eso?

Respuesta

12

Puede usar indexed desde clojure.contrib.seq. Ejemplo:

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

También puede usar map-indexed. Ejemplo:

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

Use map-indexed, como consejos de Simeon. En el contexto for es conveniente utilizar desestructuración para obtener fácil acceso tanto a la barra y los elementos de la colección:

(for [ [y x] (map-indexed vector (range 10)) ] [x y]) 

> ([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9]) 
1
(keep-indexed (fn [i el][el i]) (range 10)) 

o

(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

Además, recuerde que el uso de índices en Clojure es generalmente un olor a código

2

Me imagino que si esta pregunta aún no se ha marcado como "respondida", puede que haya otra cosa que esté buscando, y tal vez sea la flexibilidad para definir su propio contador.

Estoy de acuerdo con otros en que para el problema específico que describe, map-indexed es el camino a seguir. Sin embargo, si usted insiste en el uso de for, yo recomendaría algo como esto:

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

Rafal tiene una respuesta muy similar, excepto que el contador se iniciará siempre de cero y el incremento en 1. En mi versión se podría definir su contador como mejor le parezca Por ejemplo, cambiando el (iterate inc 0) anterior a (iterate #(+ 2 %) 10), podría tener un contador que comience en 10 e incremente en 2.