sortBy<T> function
The sortBy function can be used to create a comparator to sort
collections, comparing a and b such that:
-
If both
aandbsatisfy thetest, andthenis not provided, the order betweenaandbundefined. -
If both
aandbdon't satisfy thetest, andthenis not provided, the order betweenaandbundefined. -
Otherwise, if only
aor onlybsatisfies thetest, then the one which satisfies thetestcomes before. -
Otherwise, if both
aandbsatisfy thetest, andthenis provided, the order betweenaandbwith be given bythen.
This comparator makes it easy to create complex comparators, using the language described below. For example, suppose you have a list of numbers which you want to sort according to the following rules:
1) If present, number 14 is always the first, followed by number 15.
2) Otherwise, odd numbers come before even ones.
3) Otherwise, numbers which are multiples of 3,
4) Otherwise, numbers which are multiples of 5,
5) Otherwise, numbers come in their natural order.
int Function(int, int) compareTo = sortBy((x) => x == 14,
then: sortBy((x) => x == 15,
then: sortBy((x) => x % 2 == 1,
then: sortBy((x) => x % 3 == 0,
then: sortBy((x) => x % 5 == 0,
then: (int a, int b) => a.compareTo(b),
)))));
Important: When a cascade of sortBy is used, make sure you don't create
inconsistencies. For example, this is inconsistent: a < b and a > c and b < c.
Sorts with inconsistent rules may result in different orders for the same
items depending on their initial position, and the rules may not be followed
precisely.
Implementation
int Function(T, T) sortBy<T>(
Predicate<T> test, {
int Function(T, T)? then,
}) =>
(T a, T b) {
var ta = test(a);
var tb = test(b);
if (ta == tb) return (then == null) ? 0 : then(a, b);
return ta ? -1 : 1;
};