But the order is always the same regardless of how the table was created. If there were any other possible orders then the hash table implementation would be broken. They must be sorted for a binary search to be possible when resolving a key’s value, so there is only one possible order unless you mix keys between the array and hash parts.
See for yourself. I got 20000:("A", "H", "C", "B", "E", "D", "G", "F")
:
Code
local keys = {"A", "B", "C", "D", "E", "F", "G", "H"}
local rng = Random.new()
local function shuffle()
for i = #keys, 2, -1 do
local j = rng:NextInteger(1, i)
keys[j], keys[i] = keys[i], keys[j]
end
end
local function valueToString(v): string
if type(v) == "string" then
return string.format("%q", v)
end
return tostring(v)
end
local nameStatsList: {string} = {}
local nameStatsLookup: {[string]: number} = {}
local function checkTableOrder(t)
local order = {}
for k in pairs(t) do
table.insert(order, (valueToString(k)))
end
local name: string = "(" .. table.concat(order, ", ") .. ")"
local count: number? = nameStatsLookup[name]
if count then
nameStatsLookup[name] = count + 1
else
nameStatsLookup[name] = 1
table.insert(nameStatsList, name)
end
end
for i = 1, 10000 do
shuffle()
do -- Create a table by adding one at a time
local t = {}
for i, k in ipairs(keys) do
t[k] = true
end
checkTableOrder(t)
end
do -- Create a table by hardcoding it
assert(#keys == 8)
checkTableOrder({
[keys[1] ] = true,
[keys[2] ] = true,
[keys[3] ] = true,
[keys[4] ] = true,
[keys[5] ] = true,
[keys[6] ] = true,
[keys[7] ] = true,
[keys[8] ] = true,
})
end
end
do -- Print out the stats
local list: {string} = table.create(#nameStatsList)
for i, name: string in ipairs(nameStatsList) do
list[i] = string.format("%d:%s", nameStatsLookup[name] :: number, name)
end
print(table.concat(list, "\n"))
end
There might be an edge case if you remove the current key while iterating before shrinking the table. Waiting until a GC step might help with that, but I don’t know if that’s feasible.
My project creates constant tables programmatically and I’d like to shrink them down, considering they are kept for a long time.