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.

Sign up to request clarification or add additional context in comments.

2 Comments

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?)
@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!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.