Non-mutating sorted list in Dart

Viewed 196

I can sort a list like this in Dart:

final myList = [6, 3, 7, 1, 0, 2];
myList.sort();

However, this is a destructive sort since it mutates it in place. I'd like to do something like this:

final myList = [6, 3, 7, 1, 0, 2];
final newList = myList.sorted();

where my list stays the same but newList contains the sorted list. Dart apparently doesn't have this functionality, so how do I implement that myself?

In searching for the answer to this question my main struggle was knowing the proper way to copy a list, which wasn't as obvious as it seems like it should be. I found the answer to that, so I am also posting an answer to my original question below, Q&A style.

3 Answers

You can create a new sorted list without affecting the original list like so:

final myList = [6, 3, 7, 1, 0, 2];
final sorted = myList.toList()..sort();

Calling toList() copies the list. The .. is to get a reference to the list itself since sort() is a void function. This gives the same result:

final sorted = myList.toList();
sorted.sort();

Printing the values of both lists gives the following results:

print(myList); // [6, 3, 7, 1, 0, 2]
print(sorted); // [0, 1, 2, 3, 6, 7]

You can read more about copying lists here.

I'd suggest you to create a fixed-length list.

final myList = [6, 3, 7, 1, 0, 2];
final sortedList = myList.toList(growable: false)..sort();

It seems to me that this question is really "How can I copy a List?", and the sorting aspect is tangential.

There are multiple ways to copy an Iterable to a new List:

  • Using a method on the original Iterable: iterable.toList()
  • Using a List constructor: List.of(iterable)
  • Using the spread operator in a List literal: [...iterable]. Note that this always creates a growable List.

Note that List.from should not be used since that uses dynamic types and loses type information. Effective Dart prefers .toList().

Also note that the above applies to Sets too (iterable.toSet(), {...iterable}, Set.of(iterable)).

Related