How to remove duplicate items in a list while maintaining order?

I just saw a short video from Seth Ladd onCollections .

A collection has only unique elements (not ordered), but sometimes I need an ordered list and I want to remove all duplicates (the second occurrence of an element, for example, String should be removed from the list)

original input to list: A, B, C, B, D, Ashould result in A, B, C, D. I need to keep order. The result B, A, D, Cwould not seem to help me.

+5
source share
2 answers

This is pretty easy to implement on your own:

Iterable distinct(Iterable i) {
  var set = new Set();
  return i.where((e) {
    var isNew = !set.contains(e);
    set.add(e);
    return isNew;
  });

It would be even nicer if I Set.add()returned a bool that indicated whether the set was changed:

Iterable distinct(Iterable i) {
  var set = new Set();
  return i.where((e) => set.add(e));
}

You can, of course, record errors in queries.

: , , Iterable . Iterator , .

, Iterator, Iterable, Iterable. , Iterable Iterator, , WhereIterable/WhereIterator:

Iterable distinct(Iterable i) => new DistinctIterable(i);

class DistinctIterable<E> extends Iterable<E> {
  final Iterable<E> _iterable;

  DistinctIterable(this._iterable);

  Iterator<E> get iterator {
    return new DistinctIterator<E>(_iterable.iterator);
  }
}

class DistinctIterator<E> extends Iterator<E> {
  final Iterator<E> _iterator;
  final Set<E> _visited = new Set<E>();

  DistinctIterator(this._iterator);

  bool moveNext() {
    while (_iterator.moveNext()) {
      if (!_visited.contains(_iterator.current)) {
        _visited.add(_iterator.current);
        return true;
      }
    }
    return false;
  }

  E get current => _iterator.current;
}

, , Iterable Iterable s. , , lib - , .

+3
. :
Iterable distinct(Iterable i) {
  var map = new LinkedHashMap();
  i.forEach((x) { map[x] = true; });
  return map.keys;  // map.keys.toList() would free the map for GC.
}
+3

All Articles