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?
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.
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().
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);
});
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()));
This is not the most elegant, but it's fairly straight forward and worked for me:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With