3

I have a table that is filled with random content that a user enters. I want my users to be able to rapidly search through this table, and one way of facilitating their search is by sorting the table alphabetically. Originally, the table looked something like this:

myTable = {
    Zebra = "black and white",
    Apple = "I love them!",
    Coin = "25cents"
}

I was able to implement a pairsByKeys() function which allowed me to output the tables contents in alphabetical order, but not to store them that way. Because of the way the searching is setup, the table itself needs to be in alphabetical order.

function pairsByKeys (t, f)
    local a = {}
    for n in pairs(t) do
        table.insert(a, n)
    end
    table.sort(a, f)
    local i = 0      -- iterator variable
    local iter = function ()   -- iterator function
        i = i + 1
        if a[i] == nil then
            return nil
        else
            return a[i], t[a[i]]
        end
    end
    return iter
end

After a time I came to understand (perhaps incorrectly - you tell me) that non-numerically indexed tables cannot be sorted alphabetically. So then I started thinking of ways around that - one way I thought of is sorting the table and then putting each value into a numerically indexed array, something like below:

myTable = {
    [1] = { Apple = "I love them!" },
    [2] = { Coin = "25cents" },
    [3] = { Zebra = "black and white" },
}

In principle, I feel this should work, but for some reason I am having difficulty with it. My table does not appear to be sorting. Here is the function I use, with the above function, to sort the table:

SortFunc = function ()
    local newtbl = {}
    local t = {}
    for title,value in pairsByKeys(myTable) do
        newtbl[title] = value
        tinsert(t,newtbl[title])
    end
    myTable = t
end

myTable still does not end up being sorted. Why?

2 Answers 2

3

Lua's table can be hybrid. For numerical keys, starting at 1, it uses a vector and for other keys it uses a hash.

For example, {1="foo", 2="bar", 4="hey", my="name"}
1 & 2, will be placed in a vector, 4 & my will be placed in a hashtable. 4 broke the sequence and that's the reason for including it into the hashtable.

For information on how to sort Lua's table take a look here: 19.3 - Sort

2

Your new table needs consecutive integer keys and needs values themselves to be tables. So you want something on this order:

SortFunc = function (myTable)
    local t = {}
    for title,value in pairsByKeys(myTable) do
        table.insert(t, { title = title, value = value })
    end
    myTable = t
    return myTable
end

This assumes that pairsByKeys does what I think it does...

2
  • This solution works for me. I was trying to save as <title> = <value> (which wasn't working) and yours accomplishes the same effect by saving as "title" = <title> and "value" = <value>. Thanks!
    – pythonman
    Commented Jul 20, 2009 at 3:59
  • For those who wonder there is a definition of pairsByKeys in the documentation of lua like said in Nick Dandoulakis answer 19.3 – Sort
    – NGI
    Commented Apr 21, 2022 at 8:51