shuffle
Returns a new list with elements in shuffled order — pass a seed for a reproducible result.
Lecture
shuffle runs a Fisher-Yates shuffle over the elements of
iterable and returns a brand-new List<T> —
the input is never mutated. Called with no seed, it uses
dart:math's Random, so every call gives a
different order, exactly as you'd expect for something like a card deck
or a randomized quiz.
Pass an int seed and shuffle switches to a
seeded PRNG (a Dart port of the same Mulberry32-style generator FxTS
uses), so the same seed always produces the same order — on any
run, on any machine. That determinism is what makes seeded shuffling
useful for things like reproducible test fixtures, "daily challenge"
puzzles where everyone with today's seed sees the same layout, or
deterministic replays of a randomized simulation.
shuffleAsync is the *Async twin: it materializes
an FxAsyncIterable first (via toListAsync
internally) and then shuffles the result, so a seeded async shuffle
produces the identical order to its sync counterpart given the same seed.
Demo 1 · Seeded determinism
Same seed, same order — every time. A different seed gives a different (but still reproducible) order:
Demo 2 · shuffleAsync matches the sync order, and nothing is lost
Same seed gives the identical order whether the source is sync or async — and every element from the input is still present, just reordered:
Method spelling
xs.fxShuffle(seed) is shuffle(xs, seed), and on an
FxAsyncIterable the same name is
shuffleAsync.
It is not called shuffle, and that is not a style choice.
List.shuffle already exists in dart:core and
shuffles in place, returning void. An instance member
always beats an extension, so a List receiver would silently
call the wrong one — the prefix makes the two impossible to confuse.
final a = [1, 2, 3].fxShuffle(42); // a new List, seeded
final b = [1, 2, 3]..shuffle(); // dart:core, in place, void
Try it yourself
Exercise: give this turn order a seed so it's reproducible across app restarts instead of random every time.