Ordering of elements

Several collections implicitly support ordering of elements and help in sorting them without any effort. We can find any element with or without the filter predicate or perform a binary search within a sorted array to improve the performance of large collections. We can sort collections by providing a collection-compare function via a comparator or an object-compare method via the Comparable interface.

The Comparable interface

There are many core classes in Dart that support a native comparison via the implementation of the Comparable interface. You can implement the Comparable interface in classes that you have created to use them in collections to prevent unusual results of the sorting operation. Here, we will modify the Entity class to implement the Comparable interface. All we have to do is implement the compareTo method as shown in the following code:

class Entity implements Comparable {
  final int index;
  
  Entity(this.index);
  
  int compareTo(Entity other) {
    return this.index.compareTo(other.index);
  }
  
  @override
  String toString() => index != null? index.toString() : null;
}

The compareTo method of the Comparable interface compares this Entity class to another one. It returns:

  • A negative integer if the class is ordered before another element
  • A positive integer if the class is ordered after another element
  • A zero if the class and another element are ordered together

Now, we can safely order instances of the Entity class in our code with the sort method of the List class, as shown in the following code:

void main() {
  var first = new Entity(1),
      second = new Entity(2);
  
  var list = [second, first];
  print(list);
  // => [2, 1]  
  list.sort();
  print(list);
  // => [1, 2]
}

The Comparator type

So how can you sort a class that doesn't implement a Comparable interface? Here is an Entity2 class where implementing a Comparable interface is either impossible or not desired:

class Entity2 {
  final int index;
  
  Entity2(this.index);
  
  @override
  String toString() => index != null ? index.toString() : null;
}

In order to compare this class, you must use the Comparator type definition as follows:

typedef int Comparator<T>(T a, T b);

The sort method of all the collection classes accepts a function that matches the signature of the Comparator. Here, we pass an anonymous function to sort the comparison of our Entity2 classes as follows:

void main() {
  var list = [new Entity2(2), new Entity2(1)];
  print(list);
  // => [2, 1]
  list.sort((Entity2 a, Entity2 b) {
    return a.index.compareTo(b.index);
  });
  print(list);
  // => [1, 2]
}

As you can see, the anonymous function takes two arguments of the same type and returns an integer. This exactly matches the signature of the Comparator type definition.

If the arguments of the sort method are omitted, it uses the static compare method of the Comparable interface.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.73.175