Dart sort / compare nullable datetime

Viewed 810

I'm trying to compare list of music with releaseDate. But I can retrieve music without releaseDate and when I want to sort them, I got an error.

How can I sort / compare nullable datetime and put null releaseDate to the end?

_followedMusic.sort((a, b) {
  if (a.releaseDate != null && b.releaseDate != null)
    return a.releaseDate.compareTo(b.releaseDate);
  else
    // return ??
});

Thank you

3 Answers

If you take a look at the documentation for compareTo:

Returns a value like a Comparator when comparing this to other. That is, it returns a negative integer if this is ordered before other, a positive integer if this is ordered after other, and zero if this and other are ordered together.

https://api.dart.dev/stable/2.10.0/dart-core/Comparable/compareTo.html

So your compareTo should just result in returning the values -1, 0 or 1 according to if the compared object should be before, the same position or after the current object.

So in your case if you want your null entries to be at the start of the sorted list, you can do something like this:

void main() {
  final list = ['b', null, 'c', 'a', null];

  list.sort((s1, s2) {
    if (s1 == null && s2 == null) {
      return 0;
    } else if (s1 == null) {
      return -1;
    } else if (s2 == null) {
      return 1;
    } else {
      return s1.compareTo(s2);
    }
  });

  print(list); // [null, null, a, b, c]
}

Or if you want the null at the end:

void main() {
  final list = ['b', null, 'c', 'a', null];

  list.sort((s1, s2) {
    if (s1 == null && s2 == null) {
      return 0;
    } else if (s1 == null) {
      return 1;
    } else if (s2 == null) {
      return -1;
    } else {
      return s1.compareTo(s2);
    }
  });

  print(list); // [a, b, c, null, null]
}

Or, as @lrn suggests, make the last example in a more short and efficient way (but maybe not as readable :) ):

void main() {
  final list = ['b', null, 'c', 'a', null];

  list.sort((s1, s2) => s1 == null
      ? s2 == null
          ? 0
          : 1
      : s2 == null
          ? -1
          : s1.compareTo(s2));

  print(list); // [a, b, c, null, null]
}

what about _followdMusic.map((date) => return date ?? 1900.01.01).toList().sort(...)

the date is pseudo code, not sure how to write it. This way you put all unknown dates at one of the ends of the list.

The answer of @julemand101 also can be used with the extension function.

extension DateEx on DateTime? {
  int compareToWithNull(DateTime? date2) {
    if (this == null && date2 == null) {
      return 0;
    } else if (this == null) {
      return -1;
    } else if (date2 == null) {
      return 1;
    } else {
      return this!.compareTo(date2);
    }
  }
}
Related