Reputation: 97
I have a table consisting of key/value pairs:
mytable[a] = 1,
mytable[b] = 4,
mytable[r] = 7,
mytable[f] = 2,
etc.
I want to sort the table by the numbers. So I'd like the table to be {(a, 1), (f, 2), (b, 4), (r, 7)} I've tried using
table.sort(mytable, function(a, b) return a[2] > b[2] end)
but that didn't seem to work... Thankyou
Upvotes: 4
Views: 5804
Reputation: 38267
One way that is suggested in "Programming Lua" (I don't remember where exactly) is to extract the keys into a separate sequence, then sort the sequence, and use the resulting sorted sequence to index into the original table. Example:
keys = {}
for key, _ in pairs(mytable) do
table.insert(keys, key)
end
table.sort(keys, function(keyLhs, keyRhs) return mytable[keyLhs] < mytable[keyRhs] end)
You can then iterate over the keys to retrieve the corresponding values:
for _, key in ipairs(keys) do
print(key, mytable[key])
end
Upvotes: 5
Reputation: 473272
A table either is a set of key/value pairs or an array. OK, that's not entirely true; a table can be both, but the key/value entries will have no relationship to the array entries. That is, you can do this:
tbl = {
['a'] = 1,
['b'] = 4,
[1] = {'a', 1},
[2] = {'b', 4},
}
tbl[2]
will have no direct relationship to tbl['b']
. You can perform tbl[2] = <anything>
, and it will have no effect on the contents of tbl['b']
.
So long as the table doesn't change, you can take any pure key/value table and build an array part of it, which you can then sort however you like. Here's a function which does that:
local function build_array(tbl)
--We cannot modify `tbl` while iterating through it, so build a temp array.
local arr = {}
for key, value in pairs(tbl) do
arr[#arr + 1] = {key, value}
end
for ix, value in ipairs(arr) do
tbl[ix] = value
end
return tbl
end
Upvotes: 3