How to sort String List by newest in dart

Viewed 55

i have String List, per element contains userId+DateTime

    List<String> = [
   '9DWXpF6V4vN8oxqvsHKnOBg2Rz2022-09-14 00:07:52.707',
   '8jk9wQ0U5gNyekzNz84SDb0jDTf12022-09-12 00:07:52.704',
   '0RMRZFCifmSe2CGW6k7Rvq8gvni2022-09-13 00:07:52.704'
    ] 

now i need to sort the list from newest to oldest depends of that DateTime next to User Id

so i am trying the output look like following

  List<String> = [
   '9DWXpF6V4vN8oxqvsHKnOBg2Rz2022-09-14 00:07:52.707',
   '0RMRZFCifmSe2CGW6k7Rvq8gvni2022-09-13 00:07:52.704'
   '8jk9wQ0U5gNyekzNz84SDb0jDTf12022-09-12 00:07:52.704',
        ] 

Note : in my example i did care in day date just to explain my use case but i need to sort my list According to the most recent date and time, not only day date

How can i implement this ?

Edit i have added two fixed words 'START' and 'END' between each DateTime element so i can filter it using RegExp like following

List<String> = [
   '9DWXpF6V4vN8oxqvsHKnOBg2RzSTART2022-09-14 00:07:52.707END',
   '8jk9wQ0U5gNyekzNz84SDb0jDTf1START2022-09-12 00:07:52.704END',
   '0RMRZFCifmSe2CGW6k7Rvq8gvniSTART2022-09-13 00:07:52.704END'
    ] 

list.sort((a,b) => a[DateTime.parse(RegExp(r'|START(.*)END'))]
.compareTo(b[DateTime.parse(RegExp(START(.*)END'))]));

print(list); // it does not work

1 Answers

EDIT: Now with START and END, this should work:

RegExp regex = RegExp(r'START(.*)END$');
list.sort(
  (first, second) {
    String? firstDateString = regex.firstMatch(first)?.group(1);
    if (firstDateString == null) {
      throw ArgumentError("$first does not contain any date");
    }
    String? secondDateString = regex.firstMatch(second)?.group(1);
    if (secondDateString == null) {
      throw ArgumentError("$second does not contain any date");
    }
    DateTime firstDate = DateTime.parse(firstDateString);
    DateTime secondDate = DateTime.parse(secondDateString);
    return secondDate.compareTo(firstDate);
  }
);

UPDATE:

In order to use => we have to convert everything inside the outer curly brackets into one statement. There are two ways:

  1. We extract this into a new method which actually does the comparison of two strings. This can look like this:
int compareDateString(String first, String second) {
  String? firstDateString = regex.firstMatch(first)?.group(1);
  if (firstDateString == null) {
    throw ArgumentError("$first does not contain any date");
  }
  String? secondDateString = regex.firstMatch(second)?.group(1);
  if (secondDateString == null) {
    throw ArgumentError("$second does not contain any date");
  }
  DateTime firstDate = DateTime.parse(firstDateString);
  DateTime secondDate = DateTime.parse(secondDateString);
  return secondDate.compareTo(firstDate);
}

list.sort((first, second) => compareDateString(first, second));
// or shorter:
list.sort(compareDateString);
  1. Or we can stop throwing ArgumentErrors and shrink everything into one statement. I do not recommend this as you always should throw an error if the arguments do not contain a date. This will look like this:
list.sort((first, second) => DateTime.parse(regex.firstMatch(second)!.group(1)!).compareTo(DateTime.parse(regex.firstMatch(first)!.group(1)!)));

This one-liner expects both strings to have dates. If not you get "Null check operator used on null value". How I already mentioned, I recommend to use (1).

Related