dart –2.1.0
I’m missing something like iterator.remove() in Java. The point is that it allows for safe removal of items in a list while iterating over that list.
In Java you could do something like this:
List<String> list = new ArrayList<>();
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
iterator.remove();
}
}
And this is safe.
But in Dart, as far as I know, we would have to do something like this:
var list = [1, 2, 3, 4, 5];
var toRemove = [];
list.forEach( (e) {
if(*something*)
toRemove.add(e);
});
list.removeWhere( (e) => toRemove.contains(e));
Having a safe iterator.remove() equivalent method would be really useful!
While I’m sympathetic to the idea, we just can’t change the signature of the
Iterator
interface at the current time. Even if we introduce aCollectionIterator
with an extraremove
method and let our collections return that fromiterator
, that would still break all existing 3rd party implementations ofList
andSet
(because they only return anIterator
). Or if we remove aCollectionIterator
without changing the signature (soget iterator
just promisesIterator
, but sometimes returnsCollectionIterator
), then discoverability is very low, and the chance of cast errors is very high. That’s not a good design.Dart uses iterables in more places than Java, not just for iterating collections, so unlike Java, the vast majority of iterators will not have a functioning
remove
. Maybe it’s not the best design for Dart.Another option is to make some iterators stable wrt. removing their current object. So, if your current object is foo, then removing foo from the underlying collection will not count as a concurrent modification. I’m sure not all collections can be written to support that (a hash table may reorder on a remove, a list can’t really distinguish different modifications with the same effect on the length, etc.), so I’m not sure that’s actually viable (there’s a reason Java added the
remove
).All in all, I don’t see this happening any time soon, even though I do feel the pain. I have written that code. Check the source of
Set.removeWhere
.In fact, for your example, you can just write
list.removeWhere((e) => *something*)
. That method exists because you don’t have a good way to remove while you are iterating, so we added a combined iterate+remove operation to support the behavior.