Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams @RichardHeap yes the solution does answer my question but the question is asked differently I guess. Thanks for your help! Nomnom Nov 30, 2018 at 3:30 To reverse it you could do b.someProperty.compareTo(a.someProperty) . Or sort it and then use .reversed . Nate Bosch Feb 10, 2020 at 21:08 To reverse, just use (b,a) instead of (a,b). It's worth notinng that compareTo returns 1, 0 or -1 if you want to do more advanced sorts. Apps 247 May 16, 2020 at 7:00

In general, you can provide a custom comparison function to List.sort .

/// Desired relation | Result
/// -------------------------------------------
///           a < b  | Returns a negative value.
///           a == b | Returns 0.
///           a > b  | Returns a positive value.
int mySortComparison(SomeClass a, SomeClass b) {
  final propertyA = someProperty(a);
  final propertyB = someProperty(b);
  if (propertyA < propertyB) {
    return -1;
  } else if (propertyA > propertyB) {
    return 1;
  } else {
    return 0;
list.sort(mySortComparison);

If you're sorting some custom class you own, you alternatively could make your class implement the Comparable interface:

class MyCustomClass implements Comparable<MyCustomClass> {
  @override
  int compareTo(MyCustomClass other) {
    if (someProperty < other.someProperty) {
      return -1;
    } else if (someProperty > other.someProperty) {
      return 1;
    } else {
      return 0;

and then you can use list.sort() directly without supplying a callback.

Note that if you're sorting by a single property that already implements the Comparable interface, implementing the comparison functions is much simpler. For example:

class MyCustomClass implements Comparable<MyCustomClass> {
  @override
  int compareTo(MyCustomClass other) =>
    someProperty.compareTo(other.someProperty);

Reversing

If you want to reverse the sort order, you can:

  • Make your comparison function return a value with the opposite sign.

  • Alternatively just explicitly reverse the list after sorting:

    list = (list..sort()).reversed.toList();
    

    Sorting by multiple properties (a.k.a. subsorting)

    There are a variety of ways to sort by multiple properties.

  • A general way is to perform a stable sort for each property in reverse order of importance. For example, if you want to sort names primarily by surname and then subsort within surnames by given name, then you would first sort by given names, and then perform a stable sort by surname. See below for how to perform a stable sort.

  • Alternatively, you could sort with a comparison function that itself checks multiple properties. For example:

    class Name {
      Name({String? surname, String? givenName})
        : surname = surname ?? "",
          givenName = givenName ?? "";
      final String surname;
      final String givenName;
    int compareNames(Name name1, Name name2) {
      var comparisonResult = name1.surname.compareTo(name2.surname);
      if (comparisonResult != 0) {
         return comparisonResult;
      // Surnames are the same, so subsort by given name.
      return name1.givenName.compareTo(name2.givenName);
    
  • package:collection provides an extension to chain comparison functions so that combining them is a bit more straightforward and less error-prone:

    import 'package:collection/collection.dart';
    int compareSurnames(Name name1, Name name2) =>
        name1.surname.compareTo(name2.surname);
    int compareGivenNames(Name name1, Name name2) =>
        name1.givenName.compareTo(name2.givenName);
    final compareNames = compareSurnames.then(compareGivenNames);
    
  • My dartbag package also provides a compareIterables function that allows comparing Lists of property values in order of importance:

    import 'package:dartbag/collection.dart';
    int compareNames(Name name1, Name name2) =>
      compareIterables(
        [name1.surname, name1.givenName],
        [name2.surname, name2.givenName],
    

    Okay, I want a stable sort

    List.sort is not guaranteed to be a stable sort. If you need a stable sort, package:collection provides insertionSort and mergeSort implementations that are stable.

    But comparing might be expensive

    Suppose you have a custom comparison function that looks something like:

    int compareMyCustomClass(MyCustomClass a, MyCustomClass b) {
      var a0 = computeValue(a);
      var b0 = computeValue(b);
      return a0.compareTo(b0);
    

    The sorting process might call computeValue multiple times for the same object, which is particularly wasteful if computeValue() is expensive. In such cases, a Schwartzian transform could be faster (at the expense of using more memory). This approach maps your objects to directly sortable keys, sorts those keys, and extracts the original objects. (This is how Python's sort and sorted functions work.)

    Here's one possible implementation:

    class _SortableKeyPair<T, K extends Comparable<Object>>
        implements Comparable<_SortableKeyPair<T, K>> {
      _SortableKeyPair(this.original, this.key);
      final T original;
      final K key;
      @override
      int compareTo(_SortableKeyPair<T, K> other) => key.compareTo(other.key);
    /// Returns a sorted *copy* of [items] according to the computed sort key.
    List<E> sortedWithKey<E, K extends Comparable<Object>>(
      Iterable<E> items,
      K Function(E) toKey,
      final keyPairs = [
        for (var element in items) _SortableKeyPair(element, toKey(element)),
      ]..sort();
      return [
        for (var keyPair in keyPairs) keyPair.original,
    void main() {
      final list = <MyCustomClass>[ ... ];
      final sorted = sortedWithKeys(list, computeValue);
    

    My dartbag package provides such a sortWithKey function (and also a sortWithAsyncKey function if the key needs to be generated asynchronously).

    I was just thinking when I got to "but comparisons might be expensive" something like "I wonder how the author will approach this?" And there it was again. :) – Randal Schwartz Feb 25, 2021 at 0:19

    If you want to sort the object "objects" by the property "name" do something like this

    objects.sort((a, b) {
      return a.value['name'].toString().toLowerCase().compareTo(b.value['name'].toString().toLowerCase());
    
    extension MyIterable<E> on Iterable<E> {
      Iterable<E> sortedBy(Comparable key(E e)) =>
          toList()..sort((a, b) => key(a).compareTo(key(b)));
    

    And use

    list.sortedBy((it) => it.name);
                    Pay attention for dartx library. It is very popular and has a lot of useful extensions, mostly designed like in Kotlin.
    – Pavel Shorokhov
                    Dec 28, 2020 at 9:37
    

    Here is my contribution to this good question. If someone is facing difficulty to understand how the @Nate Bosch answer is working & you want to sort your custom model class list then you can do this way.

    1. You have to implement Comparable abstract class in your model class. It has the method compareTo which you have to override. For example, I have this StudentMarks model class which has marks property in it.

    class StudentMarks implements Comparable {
      int marks;
      StudentMarks({
        this.marks,
      @override
      int compareTo(other) {
        if (this.marks == null || other == null) {
          return null;
        if (this.marks < other.marks) {
          return 1;
        if (this.marks > other.marks) {
          return -1;
        if (this.marks == other.marks) {
          return 0;
        return null;
    

    2. Now you can call compareTo method inside the sort method.

    void _sortStudents({bool reversed: false}) {
        _students.sort((a, b) {
          return a.compareTo(b);
        if (reversed) {
          _students = _students.reversed.toList();
        setState(() {});
    

    Refer to this link you want to know more about the Comparable class

    https://api.dart.dev/stable/2.1.0/dart-core/Comparable-class.html

    If you're sorting a list of objects that properly implements Comparable, you shouldn't need to explicitly call List.sort with a callback; it should be automatic. – jamesdlin Nov 19, 2020 at 12:15 This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review – Oprimus Jan 23, 2022 at 0:33

    Using Comparatorfunction, sort Users by id.

    Comparator<UserModel> sortById = (a, b) => a.id.compareTo(b.id);
    users.sort(sortById);
    

    Now we can sort it in reversed/descending order.

    users = users.reversed.toList();
    

    To sort it in reverse order :

    list.sort((a, b) {
              return b.status.toLowerCase().compareTo(a.status.toLowerCase());
    

    What's more, you can use Comparable.compare for more clear, for example:

    class _Person {
      final int age;
      final String name;
      _Person({required this.age, required this.name});
    void _test() {
      final array = [
        _Person(age: 10, name: 'Dean'),
        _Person(age: 20, name: 'Jack'),
        _Person(age: 30, name: 'Ben'),
      // ascend with age
      // Dean Jack Ben
      array.sort((p1, p2) {
        return Comparable.compare(p1.age, p2.age);
      // decend with age
      // Ben Jack Dean
      array.sort((p1, p2) {
        return Comparable.compare(p2.age, p1.age);
      // ascend with name
      // Ben Dean Jack
      array.sort((p1, p2) {
        return Comparable.compare(p1.name, p2.name);
    

    Similar to @pavel-shorokhovs answer, but strongly typed:

    extension IterableExtensions<T> on Iterable<T> {
      Iterable<T> sortBy<TSelected extends Comparable<TSelected>>(
          TSelected Function(T) selector) =>
      toList()..sort((a, b) => selector(a).compareTo(selector(b)));
      Iterable<T> sortByDescending<TSelected extends Comparable<TSelected>>(
          TSelected Function(T) selector) =>
      sortBy(selector).toList().reversed;
    

    i had fpgrowth machine learning output/result with each element of list contains another list and frequency field i was to sort by frequency in descending order so i used a bit of recursion for that try it might work i know i am late but i am posting maybe someone else could benefit.

     sort(List<FrequentItem> fqItems) {
        int len = fqItems.length;
        if(len==2){
          if(fqItems[0].frequency>fqItems[1].frequency){
            sortedItems.add(fqItems[0]);
            sortedItems.add(fqItems[1]);
          }else{
            sortedItems.add(fqItems[1]);
            sortedItems.add(fqItems[0]);
          return;
        }else{
          FrequentItem max = fqItems[0];
          int index =0;
          for(int i=0;i<len-2;i++){
            if(max.frequency<fqItems[i+1].frequency){
              max = fqItems[i+1];
              index = i+1;
          sortedItems.add(max);
          fqItems.removeAt(index);
          sort(fqItems);
    

    In case someone is looking to sort by multiple fields the following example would work. The example is a bit raw, but the logic is simple. First, we are sorting by the league id (smaller ids first) and then sorting the elements with the same league id by the timestamp.

    final fixtures = snapshop.data!.docs..sort((a, b) {
      final leagueCompare = a['league_id'].compareTo(b['league_id']);
      if (leagueCompare == 0) {
        return a['timestamp'].compareTo(b['timestamp']);
      return leagueCompare;
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •