Comment obtenir l'index de la boucle actuelle lors de l'utilisation d'itérateur?


108

J'utilise un itérateur pour parcourir une collection et je souhaite obtenir l'index de l'élément actuel.

Comment puis je faire ça?


duplication possible de Y a
fin

1
@finnw Je ne pense pas qu'ils soient en double. Cette question se pose en utilisant Iterator, l'autre utilise la boucle for-each. Les deux questions sont résolues par une approche similaire, de sorte que les réponses sont dupliquées et non la question.
Robert

Réponses:


92

Utilisez votre propre variable et incrémentez-la dans la boucle.


6
Mais aussi voir la suggestion @ mateusz-dymczyk à propos de it.nextIndex(). Utile lorsque la collection est une liste.
noamtm

113

J'ai eu la même question et j'ai trouvé que l'utilisation d'un ListIterator fonctionnait. Similaire au test ci-dessus:

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

ListIterator iter = list.listIterator();

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

Assurez-vous d'appeler le nextIndex AVANT d'obtenir le next ().


5
Merci d'avoir mentionné `` Assurez-vous d'appeler le prochainIndex AVANT d'obtenir le prochain () ''
Gangadhar JANNU

Merci, je ne savais pas ça avant. La mise en garde que je ferais est que ListIterator est bidirectionnel alors que Iterator est unidirectionnel. Tant que vous évitez de faire des allers-retours avec ce qui est en fait un curseur, vous devriez être en sécurité.
user2910265

28

Voici un moyen de le faire en utilisant votre propre variable et en la gardant concise:

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);
}

Sortie (vous l'avez deviné):

0: zero
1: one
2: two

L'avantage est que vous n'incrémentez pas votre index dans la boucle (même si vous devez faire attention à n'appeler Iterator # next qu'une fois par boucle - faites-le simplement en haut).


3
Si vous créez l'itérateur vous-même, vous pouvez également utiliser un ListIterator et vous n'avez pas besoin de la variable int séparée.
Robert Klemme

1
Si vous utilisez une `` importation statique '' pour Arrays.asList, vous pouvez simplement écrireasList("zero", "one", "two")
karmakaze

c'est exactement la façon dont je l'ai fait avant de lire la réponse de Paul. Je découragerais fortement votre chemin, car je n'y vois aucun avantage. Pensez-vous qu'il y a un avantage (sauf celui mentionné). Pourquoi n'avez-vous pas utilisé une boucle for-each? Il n'est pas nécessaire de définir explicitement l'itérateur si vous utilisez votre propre variable.
Willi Mentzel

@progressive_overload juste si vous avez besoin d'un itérateur (comme par question, par exemple pour passer à la bibliothèque), que l'exemple ne montre pas. Dans cet exemple, vous avez une variable en dehors de la boucle et vous devez faire attention à appeler #next une fois. Dans l'exemple de Paul, il n'y a pas de variables en dehors de la boucle, mais vous devez faire attention à appeler #next et #nextIndex ensemble une fois (et en pratique, s'ils sont utilisés plus d'une fois, ils seraient tirés dans des variables locales, ce que cet exemple ne fait pas '' t montrer).
Tom Clift

23

Vous pouvez utiliser ListIteratorpour faire le comptage:

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);
}

12

Quel genre de collection? S'il s'agit d'une implémentation de l'interface List, vous pouvez simplement utiliser it.nextIndex() - 1.


4

Utilisez un ListIterator pour parcourir la collection. Si la collection n'est pas une liste pour commencer, utilisez d'abord Arrays.asList(Collection.toArray())pour la transformer en liste.


3

faites quelque chose comme ça:

        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.

        }

4
L'appel de indexOf () nécessitera une analyse supplémentaire de la liste des périphériques. Il sera plus rapide d'incrémenter simplement un compteur local.
Greg Brown

1
D'accord. ce n'est pas la solution la plus efficace.
Ensoleillé

1
Il semble que vous ayez mis à jour l'exemple pour être plus efficace.
Greg Brown


1

Regardez ici .

iterator.nextIndex()fournirait l'index de l'élément qui serait renvoyé par un appel ultérieur à next().


L'interface Iterator n'a PAS la méthode nextIndex (). Vous devez utiliser explicitement un ListIterator pour cela, mais l'OP a posé des questions spécifiquement sur Iterator.
Fran Marzoa

0

Tout ce dont vous avez besoin pour l'utiliser le iterator.nextIndex () pour renvoyer l'index actuel sur lequel se trouve l'itérateur. Cela pourrait être un peu plus facile que d'utiliser votre propre variable de compteur (qui fonctionne toujours aussi).

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); 
    }
}

Ce code parcourra la liste list1 un élément à la fois et imprimera le texte de l'élément, puis "est à l'index" puis il imprimera l'index dans lequel l'itérateur l'a trouvé. :)


1
En fait, votre code est désactivé par un car il tente d'afficher l'index APRÈS l'avoir appelé.next ().
Henrik Aasted Sørensen

0

Bien que vous ayez déjà eu la réponse, j'ai pensé à ajouter quelques informations.

Comme vous l'avez mentionné explicitement Collections, vous ne pouvez pas utiliser listIteratorpour obtenir l'index pour tous les types de collections.

Interfaces de liste - ArrayList, LinkedList, Vector et Stack.

A à la fois iterator()etlistIterator()

Définissez les interfaces - HashSet, LinkedHashSet, TreeSet et EnumSet.

A seulement iterator()

Interfaces cartographiques - HashMap, LinkedHashMap, TreeMap et IdentityHashMap

N'a pas d'itérateurs, mais peut être itéré à l'aide de keySet()/ values()ou entrySet()as keySet()et entrySet()renvoie Setet values()retourne Collection.

Il est donc préférable de l'utiliser iterators()avec une incrémentation continue d'une valeur pour obtenir l'index actuel de tout type de collection.


-1

Ce serait la solution la plus 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;

}

Testé sur gcc-9 avec -std=c++11indicateur

Production:

0
1
2
3
4

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.