Dart should have equivalent of iterator.remove() in Java

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!

Author: Fantashit

1 thought on “Dart should have equivalent of iterator.remove() in Java

  1. 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 a CollectionIterator with an extra remove method and let our collections return that from iterator, that would still break all existing 3rd party implementations of List and Set (because they only return an Iterator). Or if we remove a CollectionIterator without changing the signature (so get iterator just promises Iterator, but sometimes returns CollectionIterator), 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.

Comments are closed.