compareObject<T extends Object> function

int compareObject<T extends Object>(
  1. Object? a,
  2. Object? b, {
  3. bool nullsBefore = false,
})

The compareObject comparator is similar to the natural comparator provided by Comparable objects in their Comparable.compareTo method, to sort objects in their "natural order". The difference here is that compareObject is also able to compare some objects which are not Comparable, such as bool, MapEntry, and nulls.

In more detail:

  1. If a and b are both null, they don't have order. If only one of them is null, it will come later, unless the nullsBefore is true, in which case the null will come before.

  2. Otherwise, if a and b are both of type Comparable, compare them with their natural comparator: Comparable.compareTo.

  3. Otherwise, if a and b are map-entries (MapEntry), compare by their keys. If their keys are equal, then compare by their values.

  4. Otherwise, if a and b are booleans, compare them such as true comes after false.

  5. Otherwise, return 0, which means unordered.

Example:

[2, null, 1]..sort(compareObject);

Example with nulls coming before:

[2, null, 1]..sort((a, b) => compareObject(a, b, nullsBefore: true));

Implementation

int compareObject<T extends Object>(
  Object? a,
  Object? b, {
  bool nullsBefore = false,
}) {
  if (a == null)
    return (b == null) ? 0 : (nullsBefore ? -1 : 1);
  else if (b == null) return (nullsBefore ? 1 : -1);
  if (a is Comparable && b is Comparable) return a.compareTo(b);
  if (a is MapEntry && b is MapEntry)
    return compareObject(a.key, b.key).if0(compareObject(a.value, b.value));
  if (a is bool && b is bool) return a.compareTo(b);
  return 0;
}