Yineleyici kullanılırken geçerli döngü indeksi nasıl alınır?


108

Bir koleksiyon boyunca yinelemek için bir Yineleyici kullanıyorum ve geçerli öğenin dizinini almak istiyorum.

Bunu nasıl yapabilirim?



1
@finnw Yinelenen olduklarını düşünmüyorum. Bu soru Yineleyici kullanarak soruyor, diğeri her döngü için kullanıyor. Her iki soru da benzer bir yaklaşımla çözülür, bu nedenle cevaplar soru değil, aynıdır.
Robert

Yanıtlar:


92

Kendi değişkeninizi kullanın ve döngüde artırın.


6
Ancak @ mateusz-dymczyk hakkındaki öneriye de bakın it.nextIndex(). Koleksiyon bir Liste olduğunda kullanışlıdır.
noamtm

113

Aynı soruyu sordum ve bir ListIterator kullanarak çalıştım. Yukarıdaki teste benzer:

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

ListIterator iter = list.listIterator();

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

Aslında nextIndex'i () elde etmeden ÖNCE çağırdığınızdan emin olun.


5
'Bir sonraki dizini gerçekten () almadan ÖNCE çağırdığınızdan emin olun' dediğin için teşekkürler
Gangadhar JANNU

Teşekkürler, bunu daha önce bilmiyordum. Yapacağım uyarı, ListIterator'ın çift yönlü, Iterator'un ise tek yönlü olmasıdır. Etkili bir imleç olan şeyle ileri geri hareket etmekten kaçındığınız sürece, güvende olmalısınız.
user2910265

28

İşte bunu kendi değişkeninizi kullanarak ve kısa tutmanın bir yolu:

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

Çıktı (tahmin ettiniz):

0: zero
1: one
2: two

Bunun avantajı, döngü içinde indeksinizi artırmamanızdır (her döngüde yalnızca bir kez Yineleyici # çağırmaya dikkat etmeniz gerekse de - sadece en üstte yapın).


3
Yineleyiciyi kendiniz yaratırsanız, bir ListIterator da kullanabilirsiniz ve ayrı bir int değişkenine ihtiyaç duymazsınız.
Robert Klemme

1
Arrays.asList için bir 'statik içe aktarma' kullanırsanız, yazabilirsinizasList("zero", "one", "two")
karmakaze

Paul'ün cevabını okumadan önce aynen böyle yaptım. Sizin yolunuzdan kesinlikle vazgeçerim, çünkü bunun için bir avantaj görmüyorum. Bir avantaj olduğunu düşünüyor musunuz (bahsedilen hariç). Neden her döngü için bir döngü kullanmadınız? Kendi değişkeninizi kullanıyorsanız, Yineleyiciyi açıkça tanımlamak gerekli değildir.
Willi Mentzel

@progressive_overload, örneğin bir Yineleyiciye ihtiyacınız varsa (soru başına, örneğin kitaplığa geçmek için), örnekte gösterilmez. Bu örnekte, döngünün dışında bir değişkeniniz var ve #sonraki ifadeyi bir kez çağırmaya dikkat etmeniz gerekiyor. Paul'un örneğinde döngünün dışında değişken yoktur, ancak #sonraki ve #sonraki Dizin'i bir kez çağırırken dikkatli olmanız gerekir (ve pratikte, birden fazla kullanılırsa, yerel değişkenlere çekilirler ki bu örnekte böyle değildir '' t göster).
Tom Clift

23

ListIteratorSayma yapmak için kullanabilirsiniz :

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

Ne tür bir koleksiyon? Liste arayüzünün bir uygulamasıysa, sadece kullanabilirsiniz it.nextIndex() - 1.


4

Koleksiyon boyunca yinelemek için bir ListIterator kullanın . Koleksiyon bir Liste değilse, Arrays.asList(Collection.toArray())önce onu bir Listeye dönüştürmek için kullanmaya başlayın .


3

sadece bunun gibi bir şey yap:

        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
İndexOf () işlevinin çağrılması, cihaz listesinin ek bir taramasını gerektirir. Yerel bir sayacı basitçe artırmak daha hızlı olacaktır.
Greg Brown

1
kabul. bu en verimli çözüm değildir.
Sunny

1
Daha verimli olması için örneği güncellediniz gibi görünüyor.
Greg Brown


1

Buraya bakın .

iterator.nextIndex()sonraki çağrı ile döndürülecek eleman indeksini sağlar next().


Arayüz Yineleyicinin nextIndex () yöntemi YOKTUR. Bunun için açıkça bir ListIterator kullanmanız gerekir, ancak OP, özellikle Iterator hakkında sorguladı.
Fran Marzoa

0

Yineleyicinin üzerinde bulunduğu geçerli dizini döndürmek için onu kullanmanız gereken tek şey iterator.nextIndex (). Bu, kendi sayaç değişkeninizi kullanmaktan biraz daha kolay olabilir (yine de çalışır).

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

Bu kod, list1 listesinden her seferinde bir öğe geçer ve öğenin metnini yazdırır, ardından "indekstedir" ve ardından yineleyicinin bulduğu indeksi yazdırır. :)


1
Aslında, kodunuz bir farkla kapalı çünkü dizini onu çağırdıktan SONRA görüntülemeye çalışıyor.next ().
Henrik Aasted Sørensen

0

Cevabı zaten almış olmanıza rağmen, biraz bilgi eklemeyi düşündüm.

Koleksiyonlardan açıkça bahsettiğiniz gibi, listIteratortüm koleksiyon türleri için indeksi almak için kullanamazsınız .

Arayüzleri listeleyin - ArrayList, LinkedList, Vector ve Stack.

Hem iterator()ve hem delistIterator()

Arayüzleri ayarlayın - HashSet, LinkedHashSet, TreeSet ve EnumSet.

Sadece var iterator()

Harita arayüzleri - HashMap, LinkedHashMap, TreeMap ve IdentityHashMap

Yineleyici içermez, ancak keySet()/ values()veya entrySet()olarak kullanılarak yinelenebilir keySet()ve entrySet()döner Setve values()dönerCollection .

Bu nedenle, iterators()herhangi bir koleksiyon türü için geçerli dizini elde etmek için bir değerin sürekli artışıyla kullanılması daha iyidir .


-1

Bu en basit çözüm olacaktır!

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;

}

Gcc-9'da şununla test edildi: -std=c++11 bayrakla

Çıktı:

0
1
2
3
4

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.