1

I can sort a table with two pieces of information (the name and a second piece, such as age) with the following code:

t = {
Steve = 4,
Derek = 1,
Mike = 5,
Steph = 10,
Mary = 7,
Danny = 2
}

function pairsByKeys (t,f)  
    local a = {}

    for x in pairs (t) do
        a[#a + 1] = x
    end

    table.sort(a,f)
    local i = 0
    return function ()
    i = i + 1
    return a[i], t[a[i]]
    end
end

for a,t in pairsByKeys (t) do
    print (a,t)
end

Result:

Danny   2
Derek   1
Mary    7
Mike    5
Steph   10
Steve   4

I have a scenario where at a convention each person's name tag contains a barcode. This barcode, when scanned, enters four pieces of information about each person into a table database. This database is made up of the following pieces:

t = {
    {name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"}
    {name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"}
    {name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"}
}

But how would I change my code to sort all four entries (name, addr, age, phone) by age and keep all variables in line with one another?

I've been trying to experiment and am getting the hang of sorting a table by pairs and have a better idea how to perform table.sort. But now I want to take this another step.

Can I please receive some help from one of the programming gurus here?! It is greatly appreciated guys! Thanks!

1 Answer 1

2

You could use the age as the key of your table:

t = {
    [30] = {name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"},
    [28] = {name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"},
    [34] = {name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"},
}

function pairsByKeys (t,f)
    local a = {}

    for x in pairs (t) do
        a[#a + 1] = x
    end

    table.sort(a,f)
    local i = 0
    return function ()
        i = i + 1
        return a[i], t[a[i]]
    end
end


for a,t in pairsByKeys (t) do
    print (t.name, t.addr, t.age, t.phone)
end

EDIT

Otherwise, if you don't want to change the structure of t, you could change your iterator generating function to keep track of the indexing:

t = {
    {name = "Mike", addr = "738 Rose Rd", age = 30, phone = "333-902-6543"},
    {name = "Steph", addr = "1010 Mustang Dr", age = 28, phone = "555-842-0606"},
    {name = "George", addr = "211 Glass St", age = 34, phone = "111-294-9903"},
}

function pairsByAgeField(t,f)
    local a = {}
    local index = {}

    for _, x in pairs(t) do
        local age = x.age
        a[#a + 1] = age
        index[age] = x
    end

    table.sort(a,f)
    local i = 0
    return function ()
        i = i + 1
        return a[i], index[a[i]]
    end
end


for a,t in pairsByAgeField(t) do
    print (t.name, t.addr, t.age, t.phone)
end

Of course this makes pairsByAgeField less generally applicable than your original pairsByKeys (it assumes that the table being iterated has a given structure), but this is not a problem if you often have to deal with tables such as t in your application.

2
  • Thanks. But how would I set the keys equal to age without having to do it physically? (and for some reason, I can't seem to reply to you, @Lorenzo Donati?)
    – Pwrcdr87
    Commented Oct 3, 2013 at 19:54
  • @LorenzoDonatiOk. I just realized that i didn't have local timer = os.time() repeat until os.time() > timer + 10 at the end. It works! Thank you!
    – Pwrcdr87
    Commented Oct 3, 2013 at 20:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.