The Fisher–Yates algorithm shuffles an array uniformly in linear time. Starting at the last element, swap it with a random element at or before its position:
1 | local function shuffle(items) |
This version modifies the input table. If the original order must be retained, copy the array first:
1 | local function shuffledCopy(items) |
Lua arrays are conventionally indexed from 1, so math.random(i) is exactly the range needed. Choosing from 0 can produce a missing element, while repeatedly removing random elements adds unnecessary work and destroys the source array.
Seed policy depends on the Lua version and application. Recent Lua releases initialize randomness differently from older ones; on an older runtime, seed once during application startup rather than before every shuffle. For simulations and tests, an explicit fixed seed improves reproducibility. For security-sensitive selection, use a cryptographically secure random source instead of math.random.