compareIterables<E extends Comparable<Object>> function

int compareIterables<E extends Comparable<Object>>(
  1. Iterable<E> iterable1,
  2. Iterable<E> iterable2
)

Compares two iterables of Comparable elements in a manner similar to string comparison.

For two iterables iterable1 and iterable2, iterable1 is considered to be less than iterable2 if and only if:

  • For some k, iterable1[k].compareTo(iterable2[k]) < 0 such that for all i where 0 <= i < k, iterable1[i].compareTo(iterable2[i]) == 0.
  • iterable1.length < iterable2.length and iterable1[i].compareTo(iterable2[i]) == 0 for all i < iterable1.length.

This can be used to sort a List of objects by multiple properties. For example:

var items = getItems();
items.sort(
  (item1, item2) => compareIterables(
    [item1.majorProperty, item1.minorProperty],
    [item2.majorProperty, item2.minorProperty],
  ),
);

Implementation

int compareIterables<E extends Comparable<Object>>(
  Iterable<E> iterable1,
  Iterable<E> iterable2,
) {
  var iterator1 = iterable1.iterator;
  var iterator2 = iterable2.iterator;
  while (true) {
    var isEmpty1 = !iterator1.moveNext();
    var isEmpty2 = !iterator2.moveNext();
    if (isEmpty1 || isEmpty2) {
      if (isEmpty1 && isEmpty2) {
        return 0;
      } else if (isEmpty1) {
        return -1;
      } else {
        return 1;
      }
    }

    var value1 = iterator1.current;
    var value2 = iterator2.current;
    var comparisonResult = value1.compareTo(value2);
    if (comparisonResult != 0) {
      return comparisonResult;
    }
  }
}