views:

483

answers:

4

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!

+4  A: 

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 0, 1, 2, 3, but you can create another index array), you can sor them using table.sort.

A sorting function would be then:

function compare(a,b)
  return a[0] < b[0]
end

table.sort(items, compare)
Kornel Kisielewicz
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".
Ben Blank
I doubt you'll find a way to change the order -- it is a representation issue...
Kornel Kisielewicz
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."
sylvanaar
I've updated the question, but at this point, I'm willing to believe that there's just something weird with the particular embedded interpreter I'm working with. :-)
Ben Blank
A: 

I did a brief bit of Lua coding a couple of years ago but I'm no longer fluent in it.

When faced with a similar problem, I copied my array to another array with keys and values reversed, then used sort on the new array.

I wasn't aware of a possibility to sort the array using the method Kornel Kisielewicz recommends.

Carl Smotricz
+3  A: 

hmm, missed the part about not being able to control the iteration. there

But in lua there is usually always a way.

http://lua-users.org/wiki/OrderedAssociativeTable

Thats a start. Now you would need to replace the pairs() that the library uses. That could be a simples as pairs=my_pairs. You could then use the solution in the link above

sylvanaar
+2  A: 
Norman Ramsey