sortBy<T> function
The sortBy function can be used to create a comparator to sort
collections, comparing a
and b
such that:
-
If both
a
andb
satisfy thetest
, andthen
is not provided, the order betweena
andb
undefined. -
If both
a
andb
don't satisfy thetest
, andthen
is not provided, the order betweena
andb
undefined. -
Otherwise, if only
a
or onlyb
satisfies thetest
, then the one which satisfies thetest
comes before. -
Otherwise, if both
a
andb
satisfy thetest
, andthen
is provided, the order betweena
andb
with 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;
};