pythonman
pythonman

Reputation:

Lua - Sorting a table alphabetically

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?

Upvotes: 3

Views: 17397

Answers (2)

Norman Ramsey
Norman Ramsey

Reputation: 202675

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...

Upvotes: 2

Nick Dandoulakis
Nick Dandoulakis

Reputation: 43140

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

Upvotes: 3

Related Questions