First, avoid using Iterable.forEach
except for trivial cases. If you want element indices, just use a normal looping construct (e.g. for
, while
). Also see https://stackoverflow.com/a/65420010/.
In your example code, you unconditionally remove each item, so you could just call List.clear()
at the end, which would be much simpler and more efficient. That should be O(1).
If you don't want to remove all items and instead need to conditionally remove multiple items, there are a few ways you could do it.
Use List.removeWhere
if possible. I expect this to be O(n) with respect to the length of the list.
Process the items from last to first so that removing an element from the list does not affect iteration:
for (var i = textMap.results.length - 1; i >= 0; i -= 1) {
print(textMap.results[i]); // Do something with the element.
if (shouldRemove(textMap.results[i])) {
textMap.results.removeAt(i);
}
}
If you must process the elements in order, you can first collect a list of indices to remove and then remove them separately:
var indicesToRemove = <int>[];
for (var i = 0; i < textMap.results.length; i += 1) {
print(textMap.results[i]); // Do something with the element.
if (shouldRemove(textMap.results[i])) {
indicesToRemove.add(i);
}
}
// Remove in reverse order so that removing items does not affect
// unprocessed indices.
for (var index in indicesToRemove.reversed) {
textMap.results.removeAt(index);
}
Alternatively use a while
loop that conditionally increments the list index:
var i = 0;
while (i < textMap.results.length) {
print(textMap.results[i]); // Do something with the element.
if (shouldRemove(textMap.results[i])) {
textMap.results.removeAt(i);
// Iterate again at the same index.
continue;
}
i += 1;
}
The last three approaches would be O(m*n) where n is the length of the list and m is the number of items to remove.