Home > Software design >  Dart orderBy sorting for iterators
Dart orderBy sorting for iterators

Time:10-14

The dart .sort() method can't be used as part of the iterator chain.

For example, I can't do the next

arr.sort().take(5);

In C# they have OrderBy() and OrderByDesc() which can be used to sort by class field and can be used as part of the iterators chain.

CodePudding user response:

import 'package:collection';

final sortedIterator = someIterable.sorted().take(5);

You should study both package:async and package:collection. Lots of bonus functionality maintained by the core Dart team.

CodePudding user response:

Inherently you must know all of the elements of a collection if you want to sort it. If you have an Iterable, you therefore cannot avoid converting it to a List first, and once you do that, you can just use List.sort.

Since List.sort() mutates a List without returning it, you also will need to use the cascade operator (..) to refer to that mutated List:

var firstFive = (someIterable.toList()..sort()).take(5);

CodePudding user response:

You can write a simple extension function:

typedef CompareBy<T, TOrder> = TOrder Function(T item);

extension IteratorUtilities<T> on Iterable<T> {
  List<T> orderBy<TOrder extends Comparable<TOrder>>(CompareBy<T, TOrder> fn) {
    var list = toList();
    list.sort((a, b) => fn(a).compareTo(fn(b)));

    return list;
  }

  List<T> orderByDesc<TOrder extends Comparable<TOrder>>(CompareBy<T, TOrder> fn) {
    var list = toList();
    list.sort((a, b) => fn(b).compareTo(fn(a)));

    return list;
  }
}

Usage examples

Simple sorting:

["x", "ab", "c"].orderBy((c) => c).take(2);

Sorting by user name:

users.orderBy((u) => u.name).take(2);
  • Related