2

I have a table mapping strings to numbers like this:

t['a']=10
t['b']=2
t['c']=4
t['d']=11

From this I want to create an array-like table whose values are the keys from the first table, ordered by their (descending) values in the first table, like this:

T[1] = 'd' -- 11
T[2] = 'a' -- 10
T[3] = 'c' -- 4
T[4] = 'b' -- 2

How can this be done in Lua?

3

3 Answers 3

9
-- Your table
local t = { }
t["a"] = 10
t["b"] = 2
t["c"] = 4
t["d"] = 11

local T = { } -- Result goes here

-- Store both key and value as pairs
for k, v in pairs(t) do
  T[#T + 1] = { k = k, v = v }
end

-- Sort by value
table.sort(T, function(lhs, rhs) return lhs.v > rhs.v end)

-- Leave only keys, drop values
for i = 1, #T do
  T[i] = T[i].k
end

-- Print the result
for i = 1, #T do
  print("T["..i.."] = " .. ("%q"):format(T[i]))
end

It prints

T[1] = "d"
T[2] = "a"
T[3] = "c"
T[4] = "b"
2
  • Yes, right. But maybe replacing T[#T+1] = v with table.insert(T, v) would be a little more "coding by the book"-flavoured, even though it has more characters in it.
    – AndersH
    Commented Mar 2, 2011 at 14:44
  • #T+1 is by the book. table.insert, ideologically, is for stacks and such — when you have to pair it with table.remove (or for inserting at other places of table than its end of course). Commented Mar 2, 2011 at 15:35
2

Alexander Gladysh's answer can be simplified slightly:

-- Your table
local t = { }
t["a"] = 10
t["b"] = 2
t["c"] = 4
t["d"] = 11

local T = { } -- Result goes here

-- Store keys (in arbitrary order) in the output table
for k, _ in pairs(t) do
  T[#T + 1] = k
end

-- Sort by value
table.sort(T, function(lhs, rhs) return t[lhs] > t[rhs] end)

-- Print the result
for i = 1, #T do
  print("T["..i.."] = " .. ("%q"):format(T[i]))
end
1

Tables in Lua do not have an order associated with them.

When using a table as an array with sequential integer keys from 1 to N, the table can be iterated in order using a loop or ipairs().

When using keys that are not sequential integers from 1 to N, the order can not be controlled. To get around this limitation a second table can be used as an array to store the order of the keys in the first table.

Not the answer you're looking for? Browse other questions tagged or ask your own question.