Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to sort a list based on two values

Tags:

flutter

dart

I have a list in which I want to sort based on two values date and the status like this:

pollsList.sort((a, b) => b.active.compareTo(a.active));

  pollsList.sort((a, b) {
    return b.actualStartDatetime.compareTo(a.actualStartDatetime);
  });

where active == 90 if it's active and -90 if it's not.

I want to sort the list based on the date and then based on the date.

I want the newest at the top and always the closed to be after the active items.

But this will result the list only being sorted by the date. How do I sort it by both values?

like image 719
mrs.tat Avatar asked Apr 30 '19 12:04

mrs.tat


People also ask

How do you sort a list by two values in Python?

To sort a Python list by two fields, we can use the sorted function. to call sorted to return the list items sorted by calling it with the key argument set to a lamnda function that has a tuple of values to sort by. We sort x[1] in descending order since we have a minus sign before the value.

How do you sort a list of tuples based on two values?

In python, if you want to sort a list of tuples by the second element then we have the function called sort() and by using lambda function as a key function. A custom comparator is a key function in sort().


3 Answers

You want to sort the list so that a later start time is sorted before an earlier start time, and if both elements have the same start time, then sort active elements before inactive elements.

What you have attempted is to sort the list twice. That only works if the sorting algorithm is stable, that is, if elements that are equal wrt. the second sort comparison stay in the order they were put by the first sort. Dart's sort does not promise to be stable, so this is not a safe approach. Even if it appears to work, it is quite possible to have a sorting algorithm that is stable for small lists and not for larger lists.

What you should do instead is to create a single comparison function that does both compares at once. First compare the start times. If those are not equal, you are done, otherwise compare the activities as well.

pollsList.sort((a, b) {
  int cmp = b.actualStartDatetime.compareTo(a.actualStartDatetime);
  if (cmp != 0) return cmp;
  return b.active.compareTo(a.active);
});

If you want all inactive elements to be sorted before all active elements, and then have each of these groups sorted by start time, you do the comparison in the opposite order:

pollsList.sort((a, b) {
  int cmp = b.active.compareTo(a.active);
  if (cmp != 0) return cmp;
  return b.actualStartDatetime.compareTo(a.actualStartDatetime);
});
like image 59
lrn Avatar answered Oct 07 '22 23:10

lrn


i solve this by making two columns into one. "${a.active}${a.actualStartDatetime}" and compare it to b.

data.sort((a, b) =>  ("${a.active}${a.actualStartDatetime}").toString()
.compareTo(("${b.status}${b.actualStartDatetime.toUpperCase()}").toString()));
like image 7
Jalo Lagunoy Avatar answered Oct 07 '22 23:10

Jalo Lagunoy


This is not the most elegant, but it's fairly straight forward and worked for me:

  1. Divide your original list into 2 new lists based on the first sorting criteria;
  2. Sort each new list by the second criteria;
  3. Finally, combine the 2 new lists into a final, sorted list;

For example:

    List<Polls> activePollsList;
    List<Polls> inactivePollsList;
    List<Polls> finalSortedPollsList;
    
    activePollsList.addAll(pollsList.where((Poll poll) => poll.isActive == true));
    activePollsList.sort((a, b) => a.actualStartDateTime.compareTo(b.actualStartDateTime));
    
    inactivePollsList.addAll(pollsList.where((Polls poll) => poll.isActive == false));
    inactivePollsList.sort((a, b) => a.actualStartDateTime.compareTo(b.actualStartDateTime));
    
    finalSortedPollsList = activePollsList + inActivePollsList;

That finalSortedList will retain the sorting done by the two lists.

Note in the above I'm making the assumption that your pollsList is a list of custom objects called Polls, but you would want to change Poll in the above code to whatever your custom object is named.

Again, not the most elegant solution, but until Dart allows for multiple sorting criteria this worked for me.

like image 1
stfn3000 Avatar answered Oct 07 '22 23:10

stfn3000