¿Cómo obtener el índice de bucle actual al usar Iterator?

107

Estoy usando un iterador para iterar a través de una colección y quiero obtener el índice del elemento actual.

¿Cómo puedo hacer eso?

Mahmoud Saleh
fuente
1
@finnw No creo que estén duplicados. Esta pregunta se hace usando Iterator, la otra está usando for-each loop. Ambas preguntas se resuelven con un enfoque similar, por lo que las respuestas son duplicadas, no la pregunta.
Robert

Respuestas:

92

Use su propia variable e increméntela en el ciclo.

Chris Diver
fuente
6
Pero también vea la sugerencia de @ mateusz-dymczyk sobre it.nextIndex(). Útil cuando la colección es una Lista.
noamtm
113

Tenía la misma pregunta y descubrí que usar un ListIterator funcionaba. Similar a la prueba anterior:

List<String> list = Arrays.asList("zero", "one", "two");

ListIterator iter = list.listIterator();

while (iter.hasNext()) {
    System.out.println("index: " + iter.nextIndex() + " value: " + iter.next());
}

Asegúrese de llamar al nextIndex ANTES de obtener el next ().

Pablo
fuente
5
Gracias por mencionar 'Asegúrese de llamar al nextIndex ANTES de obtener el next ()'
Gangadhar JANNU
Gracias, no sabía nada de esto antes. La advertencia que haría es que ListIterator es bidireccional mientras que Iterator es unidireccional. Siempre que evite moverse hacia adelante y hacia atrás con lo que efectivamente es un cursor, debe estar seguro.
user2910265
28

Aquí hay una forma de hacerlo usando su propia variable y manteniéndola concisa:

List<String> list = Arrays.asList("zero", "one", "two");

int i = 0;
for (Iterator<String> it = list.iterator(); it.hasNext(); i++) {
    String s = it.next();
    System.out.println(i + ": " + s);
}

Salida (lo adivinaste):

0: zero
1: one
2: two

La ventaja es que no incrementas tu índice dentro del ciclo (aunque debes tener cuidado de llamar al Iterador # siguiente solo una vez por ciclo, solo hazlo en la parte superior).

Tom Clift
fuente
3
Si crea el iterador usted mismo, también puede usar un ListIterator y no necesita la variable int separada.
Robert Klemme
1
Si usa una 'importación estática' para Arrays.asList, simplemente puede escribirasList("zero", "one", "two")
karmakaze
así es exactamente como lo hice antes de leer la respuesta de Paul. Desaconsejaría fuertemente su camino, porque no veo ninguna ventaja en ello. ¿Crees que hay una ventaja (excepto por la mencionada)? ¿Por qué no usaste un bucle para cada uno? No es necesario definir el iterador explícitamente si usa su propia variable.
Willi Mentzel
@progressive_overload solo si necesita un iterador (según la pregunta, por ejemplo, para pasar a la biblioteca), que el ejemplo no muestra. En este ejemplo, tiene una variable fuera del bucle y debe tener cuidado de llamar a #next una vez. En el ejemplo de Paul, no hay variables fuera del ciclo, pero debe tener cuidado de llamar a #next y #nextIndex juntos una vez (y en la práctica, si se usan más de una vez, se incluirán en variables locales, lo que ese ejemplo no hace ' t mostrar).
Tom Clift
23

Puede usar ListIteratorpara hacer el conteo:

final List<String> list = Arrays.asList("zero", "one", "two", "three");

for (final ListIterator<String> it = list.listIterator(); it.hasNext();) {
    final String s = it.next();
    System.out.println(it.previousIndex() + ": " + s);
}
Robert Klemme
fuente
12

¿Qué tipo de colección? Si se trata de una implementación de la interfaz List, entonces podría usar it.nextIndex() - 1.

Mateusz Dymczyk
fuente
4

Utilice un ListIterator para recorrer la colección. Si la colección no es una lista, para empezar, utilice Arrays.asList(Collection.toArray())para convertirla en una lista primero.

Jatin
fuente
3

solo haz algo como esto:

        ListIterator<String> it = list1.listIterator();
        int index = -1;
        while (it.hasNext()) {
            index++;
            String value = it.next();
            //At this point the index can be checked for the current element.

        }
Soleado
fuente
4
Llamar a indexOf () requerirá un escaneo adicional de la lista de dispositivos. Será más rápido simplemente incrementar un contador local.
Greg Brown
1
convenido. esta no es la solución más eficiente.
Soleado
1
Parece que actualizó el ejemplo para que sea más eficiente.
Greg Brown
2

Use un int e increméntelo dentro de su ciclo.

Florian Reischl
fuente
1

Vea aquí .

iterator.nextIndex()proporcionaría un índice de elemento que sería devuelto por una llamada posterior a next().

Alegre
fuente
La interfaz Iterator NO tiene el método nextIndex (). Necesita usar explícitamente un ListIterator para eso, pero el OP cuestionó específicamente sobre Iterator.
Fran Marzoa
0

Todo lo que necesita para usarlo es el iterator.nextIndex () para devolver el índice actual en el que se encuentra el iterador. Esto podría ser un poco más fácil que usar su propia variable de contador (que también funciona).

public static void main(String[] args) {    
    String[] str1 = {"list item 1", "list item 2", "list item 3", "list item 4"};
    List<String> list1 = new ArrayList<String>(Arrays.asList(str1));

    ListIterator<String> it = list1.listIterator();

    int x = 0;

    //The iterator.nextIndex() will return the index for you.
    while(it.hasNext()){
        int i = it.nextIndex();
        System.out.println(it.next() + " is at index" + i); 
    }
}

Este código pasará por la lista list1 un elemento a la vez e imprimirá el texto del elemento, luego "está en el índice" y luego imprimirá el índice en el que lo encontró el iterador. :)

Ryan
fuente
1
En realidad, su código está desactivado en uno porque intenta mostrar el índice DESPUÉS de llamarlo.next ().
Henrik Aasted Sørensen
0

Aunque ya tenía la respuesta, pensó en agregar algo de información.

Como mencionó Colecciones explícitamente, no puede usar listIteratorpara obtener el índice para todos los tipos de colecciones.

Listar interfaces : ArrayList, LinkedList, Vector y Stack.

Tiene ambos iterator()ylistIterator()

Establecer interfaces : HashSet, LinkedHashSet, TreeSet y EnumSet.

Sólo tiene iterator()

Interfaces de mapas : HashMap, LinkedHashMap, TreeMap e IdentityHashMap

No tiene iteradores, pero se puede iterar mediante keySet()/ values()o entrySet()as keySet()y entrySet()devuelve Sety values()devuelveCollection .

Por lo tanto, es mejor usarlo iterators()con un incremento continuo de un valor para obtener el índice actual para cualquier tipo de colección.

Vignesh Raja
fuente
-1

¡Esta sería la solución más simple!

std::vector<double> v (5);

for(auto itr = v.begin();itr != v.end();++itr){

 auto current_loop_index = itr - v.begin();

  std::cout << current_loop_index << std::endl;

}

Probado en gcc-9 con -std=c++11bandera

Salida:

0
1
2
3
4

Camarada
fuente