I just wanted to share this method with you all for shuffling an array. The way you can shuffle it is using the less-known Random.new():Shuffle(table) method. I was going to go write a shuffling algorithm manually, but found this gold instead!
I could be mistaken, as I am not too experienced in this all, but if you used table.sort in this fashion:
local function shuffle(t)
local rng = Random.new()
table.sort(t, function(a, b)
return rng:NextNumber() < 0.5
end)
end
The result would be a potentially biased shuffle in that table.sort assumes a consistent comparator—like when you use it to sort by greater value or something. If you feed it random numbers like rng in our example here, some orders might be more likely than others depending on the sorting algorithm’s internal structure.
The alternative then would be the Fisher-Yates shuffle, which should give you uniform distribution. Instead of manually programming that (which you can still do if you like using table.sort and Random.new():NextInteger()), it appears we can just use Random’s :Shuffle() for sake of convenience.
Here’s what it would look like if you wanted to sort it using Fisher-Yates manually:
local function shuffle(t)
local rng = Random.new()
for i = #t, 2, -1 do
local j = rng:NextInteger(1, i)
t[i], t[j] = t[j], t[i]
end
end
Let me know what you think, this is a fascinating topic I love it!
I want to make a quick point: Fisher-yates is the proper way to perform an array shuffle (which is what rng:Shuffle uses according to the docs).
Simply sorting with random numbers doesn’t work because the table.sort algorithm relies on stable values per key. You’ll get in error: invalid order function for sorting.
Ahhhh, yeah that makes a lot of sense. The method with table.sort() is very likely to produce similar patterns with every iteration, hence why it’s not really a uniform distribution.