sortinglualua-tableasort

Associatively sorting a table by value in Lua


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!


Solution

  • 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)