我正在使用QLinkedList
循环遍历foreach
,但如果项目符合特定条件,我需要删除它们。在不搞乱循环的情况下,这样做的正确方法是什么?
foreach( Object obj, myLinkedList )
{
if( obj.val == BAD_VAL )
// remove the item from myLinkedList
}
我发现other questions可以解决这个问题,但不适用于链接列表等一般情况。
我想知道其他数据结构(如QSet
,QHash
等),如果可能的话。感谢
答案 0 :(得分:16)
针对具体案例:
显然不应使用foreach
循环来修改列表,因为foreach
循环实际上正在处理原始列表的副本。如果你修改它,不仅会因为隐式共享和写入时修改而受到惩罚,但是一旦你退出循环,你的更改也会被丢弃。
实现此目的的正确方法是使用迭代器。我更喜欢Java风格的迭代器。您会注意到每个列表类型都有迭代器类,它们提供简单的迭代器。对于QLinkedList
示例,有一个类QMutableLinkedListIterator
。它可以使用如下:
添加了我的评论Qt documentation:
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
}
}
对于一般情况:
如果你使用的是QLinkedList
以外的Qt数据结构,很可能会有一个迭代器类供你使用。如果要修改列表,请使用Mutable版本。每种API的API大致相同。以下是课程:
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
答案 1 :(得分:0)
我还可以建议一种昂贵但简单的方法来做到这一点。创建另一个列表并将 good 对象复制到其中。然后用新的列表替换旧列表。
QLinkedList<Object> new_list;
foreach(Object obj, myLinkedList) {
if(obj.val != BAD_VAL) {
new_list << obj;
}
}
list = new_list;
如果您的列表内容很大,请不要这样做。