2013-07-05 19 views
5

foreach döngüsünü kullanarak QLinkedList aracılığıyla yineliyorum, ancak belirli bir koşulla eşleşiyorsa öğeleri silmem gerekiyor. Döngüyü karıştırmadan bunu yapmanın doğru yolu nedir?Foreach döngüsünü kullanarak Qt veri yapılarını değiştirmenin uygun yolu

foreach(Object obj, myLinkedList) 
{ 
    if(obj.val == BAD_VAL) 
     // remove the item from myLinkedList 
} 

buldum other questions adresi bu bu tür, ancak genel durumda böyle bağlantılı liste olarak.

Mümkünse diğer veri yapıları (QSet, QHash, vb.) Hakkında da bilgi edinmek istiyorum. Belirli bir vaka için teşekkürler

+0

@hyde Bu soruyu sorduğum soruya bütünüyle bağladım, sorduğum şeyin tamamını ele almadığını belirttim. QList ve QLinkedList arasında bir fark var. Benzerler, ama * aynı değil. –

+0

Evet, görebildiğim kadarıyla, soruya cevap veriyor. Qt, "foreach" öğesini kullandığınızda kabın sığ bir kopyasını alır. Orijinal kapsayıcı yapısını değiştirirseniz, Qt'nin tüm kapsayıcıya yeni bir derin kopya (yazma anlamında kopya) yapması gerekir. Kısacası, bunun için 'foreach' kullanmayın. Ve semantikler her Qt konteyneri için aynıdır. – hyde

cevap

14

: Görünüşe foreach döngüler hiç listeyi değiştirmek için kullanılmamalıdır

, foreach döngü aslında üzerinde çalışıyor çünkü orijinal listenin kopyalayın. Bunu değiştirirseniz, sadece örtülü paylaşım ve yazım üzerinde değişiklik nedeniyle bir cezayla uğraşmakla kalmaz, aynı zamanda döngüden çıktıktan sonra değişiklikleriniz de iptal edilir.

Bunu gerçekleştirmenin doğru yolu bir yineleyici kullanmaktır. Java stili yineleyicileri tercih ederim. Basit yineleyiciler sağlayan her liste türü için yineleyici sınıfları olduğunu fark edeceksiniz. QLinkedList örneği için QMutableLinkedListIterator sınıfı vardır. Benim yorumlarla Qt documentation itibaren

eklendi:

QMutableLinkedListIterator<int> i(list); // pass list as argument 
while (i.hasNext()) { 
    int val = i.next();     // retrieve value of current item 
    if (val < 0) { 
     i.setValue(-val);    // change/set value of current item 
    } else if (val == 0) { 
     i.remove();      // delete current item 
    } 
} 


genel durum için: Aşağıdaki gibi kullanılabilir

diğer bir Qt veri yapısını daha kullanıyorsanız QLinkedList, şansınız iyi, sizin için bir yineleme sınıfı var. Listeyi değiştirmek isterseniz, Değiştirilebilir sürümünü kullanın. API, bunların her biri için kabaca aynıdır. İşte bu sınıflar:

Structure | Immutable Case  | Mutable Case 
----------------------------------------------------- 
QList  | QListIterator  | QMutableListIterator 
QLinkedList | QLinkedListIterator | QMutableLinkedListIterator 
QHash  | QHashIterator  | QMutableHashIterator 
QMap   | QMapIterator   | QMutableMapIterator 
QSet   | QSetIterator   | QMutableSetIterator 
QStringList | QStringListIterator | QMutableStringListIterator 
QVector  | QVectorIterator  | QMutableVectorIterator 
0

Bunun için pahalı ama basit bir yol önerebilirim. Başka bir liste oluşturun ve iyi nesnesini kopyalayın. Sonra eski listeyi yenisiyle değiştirin. Liste içeriği büyükse, bunu yapmayın.