I have a key => value table I'd like to sort in Lua. The keys are all integers, but aren't consecutive (and have meaning). Lua's only sort function appears to be table.sort
, which treats tables as simple arrays, discarding the original keys and their association with particular items. Instead, I'd essentially like to be able to use PHP's asort()
function.
What I have:
items = {
[1004] = "foo",
[1234] = "bar",
[3188] = "baz",
[7007] = "quux",
}
What I want after the sort operation:
items = {
[1234] = "bar",
[3188] = "baz",
[1004] = "foo",
[7007] = "quux",
}
Any ideas?
Edit: Based on answers, I'm going to assume that it's simply an odd quirk of the particular embedded Lua interpreter I'm working with, but in all of my tests, pairs()
always returns table items in the order in which they were added to the table. (i.e. the two above declarations would iterate differently).
Unfortunately, because that isn't normal behavior, it looks like I can't get what I need; Lua doesn't have the necessary tools built-in (of course) and the embedded environment is too limited for me to work around it.
Still, thanks for your help, all!
You seem to misunderstand something. What you have here is a associative array. Associative arrays have no explicit order on them, e.g. it's only the internal representation (usually sorted) that orders them.
In short -- in Lua, both of the arrays you posted are the same.
What you would want instead, is such a representation:
items = {
{1004, "foo"},
{1234, "bar"},
{3188, "baz"},
{7007, "quux"},
}
While you can't get them by index now (they are indexed 1, 2, 3, 4, but you can create another index array), you can sort them using table.sort
.
A sorting function would be then:
function compare(a,b)
return a[1] < b[1]
end
table.sort(items, compare)
This does not appear to be true for Lua, by my tests. When iterating over a table using
pairs()
, the order is stable and corresponds to the order in which the items were added. Furthermore, I don't have the option of changing the way the data is stored; I'm feeding the result into a 3rd-party library which displays the items to the user in "pairs()
order".pairs returns the data in hash order - it may be stable - but it is not the order in which the items were added. From lua-users wiki " Note, there is no guarantee as to the order in which keys will be stored in a table when using dictionaries so the order of retrieval of keys using pairs() is not guaranteed. This caveat even applies to the indexed portion of the table, or in a table that is not being used as a dictionary at all and has only indices as keys."
By the way,
return a[0] < b[0]
bit me too many times as well. Lua indexes are 1-based.@Stavros - omg, it's so wierd that it took so long for anyone to notice it!
since we want to compare the strings, shouldn't it be
return a[2] < b[2]
?