Pwrcdr87
Pwrcdr87

Reputation: 965

Sorting a Table Containing Tables

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!

Upvotes: 1

Views: 227

Answers (1)

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.

Upvotes: 2

Related Questions