October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk3 min

Schwartzian Transform in Dart: Common Mistakes and FAQs

Use decorate-sort-undecorate in Dart to compute each sort key once, keep keys paired with items, and control ties without relying on sort stability.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To sort Dart objects by an expensive computed value without recalculating that value during comparisons, compute the key once per item, store it beside the item, sort the stored pairs, then extract the items. The essential detail is to call .toList() on the decorated values: Iterable.map is lazy and does not cache conversions.

What is the Schwartzian transform?

Also called decorate-sort-undecorate, the Schwartzian transform has three stages: attach a derived sort key to each item, sort those decorated items by the saved key, then remove the decoration. It is useful when calculating a key inside a comparator would repeat costly work. The approach uses extra storage, so it is a trade-off rather than a guaranteed speedup.

As an Amazon Associate I earn from qualifying purchases.

How to sort by a computed property in Dart

This example uses Dart records to keep each item paired with its key:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
final decorated = items
    .map((item) => (item: item, key: expensiveKey(item)))
    .toList();

decorated.sort((a, b) => a.key.compareTo(b.key));
final sortedItems = decorated.map((entry) => entry.item).toList();
  1. Decorate: calculate the key once for each input item and store the item and key together.
  2. Materialize: call .toList() so the decorations are stored rather than lazily recalculated.
  3. Sort: compare the saved keys in the comparator.
  4. Undecorate: extract the original items into the result list.

This record syntax requires a Dart version that supports records. For older language versions, use a small typed helper class with item and key fields. Check the project’s SDK constraint; the available documentation does not establish a minimum SDK version here.

Why materializing map() matters

Dart’s Iterable.map is lazy: it applies the conversion as you iterate, and it does not cache converted values between iterations. If you keep a mapped iterable as though it were saved key storage, iterating it again can run the key calculation again. Calling .toList() on the decorated iterable creates the concrete list needed for this technique.

Keep duplicate keys paired with their items

Make one decoration for every input item, even when several items have the same key. Sorting those pairs keeps each item attached to its own key. Do not use a map from key to item as a substitute when keys may repeat: Map.fromIterable permits duplicate generated keys, and later values overwrite earlier ones.

Make tie ordering explicit when it matters

The reviewed Dart List.sort documentation does not promise a stable sort, so equal keys should not be assumed to retain their input order. Store each item’s original index and use it as a secondary comparison when the primary keys compare equal:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
final decorated = items
    .asMap()
    .entries
    .map((entry) => (
          item: entry.value,
          key: expensiveKey(entry.value),
          index: entry.key,
        ))
    .toList();

decorated.sort((a, b) {
  final byKey = a.key.compareTo(b.key);
  return byKey != 0 ? byKey : a.index.compareTo(b.index);
});

final sortedItems = decorated.map((entry) => entry.item).toList();

The index makes the desired tie order part of the comparator rather than relying on a sort stability guarantee. Dart comparator callbacks should return a negative number when the first value comes earlier, zero when the values are equivalent, and a positive number when the first comes later.

What sorting changes about the source list

List.sort sorts the list on which it is called. The examples sort a separate decorated list, leaving the original list’s order intact, and create a separate output list. Dart’s List API also says changing a list’s length during operations such as sorting is generally disallowed.

Plan the key and comparator for your data

Decide the ordering rules before implementing the comparator. For example, specify whether null sorts first or last, whether strings need case folding or locale-aware collation, and how equal primary keys should be ordered. Precompute expensive normalization in the decoration, and test representative edge cases. The comparator must be consistent; these ordering choices are application-specific, not defaults established by the APIs cited here.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When is the transform worthwhile?

Compare the cost of repeated key calculation with the extra allocation and storage of decorated values. The benefit depends on the data, key function, sort behavior, and runtime. No Dart-specific benchmark or performance crossover figure is established here, so benchmark representative data before claiming a speed gain.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.