Sort tables within table in a numerical order

I have this table which I want to show it’s content in a tableView:

    local table = {         item1 = {name="Item1", num=1, model=5040},         item2 = {name="Item2", num=2, model=5050},         item3 = {name="Item3", num=3, model=5060},    }

Using (for k,v in pairs) doesn’t return the elements in a numerical order aka the order of their creation. I tried “table.sort()” but it also doesn’t work with this kind of a table. I was wondering if there is a way to achieve what I want.

have you tried?

for i=1, #table do   ...... end

This doesn’t work with this kind of table. It returns nothing.

    for i=1,#table do         print( table[i] ) ---\> nothing     end

This does not work because you’re not creating a table with a numeric index but with the strings named “item1”, “item2” and so on. In this case, Lua uses a hash table for the table and so there’s no sorting available by nature of the data struct.

If you remove the string based key it’ll work as expected.

[lua]

local tab = {

    {name=“Item1”, num=1, model=5040},

    {name=“Item2”, num=2, model=5050},

    {name=“Item3”, num=3, model=5060},    

}

for i = 1,#tab do

    local entry = tab[i]

    print( entry.name )

end

[/lua]

Thanks for the reply.

I’m already familiar with the method you used, however, I still would like to use a table with key,value structure because at a certain point in my app I would like to access a specific key of that table and change one of its values. 

pairs is a slow operation and should be avoided… always process based on ordinal

If you always have a field name=“item1” etc. then, depending on how often you modify the table and how big your table is, a simple solution could be to just iterate over the table until you find the entry your looking for.

Another option is a second table used as a lookup for your current sort order.

[lua]

local tab = {

    item1 = {name=“Item1”, num=1, model=5040},

    item2 = {name=“Item2”, num=2, model=5050},

    item3 = {name=“Item3”, num=3, model=5060},    

}

local sortLookup = {

    “item3”,

    “item2”,

    “item1”,

}

for i = 1,#sortLookup do

    local entry = tab[sortLookup[i]]

    print( entry.name )

end

[/lua]

You’d have to keep both tables synchronized but that’s usually not a problem. This way you can also create sorting orders in whatever way you want without changing your original table.

@Michael Flad

Thanks a lot. that definitely solved my problem. I will always try in the future to keep my usage of key,value tables to a minimum. 

Glad this helped.

But you don’t need to minimize the usage of tables in general (of course depends on your project/size). They’re the very core data struct in Lua and in combination with the rest of the language a very flexible one too.

F.i. you could generate the lookup tables with a small function and do even complex sorting if required.

(had to paste the code without formatting as, somehow, all linefeed got lost)

local tab = {

    item1 = {name=“Item1”, num=4, model=6040},

    item2 = {name=“Item2”, num=6, model=5050},

    item3 = {name=“Item3”, num=5, model=4060},    

}

local function buildSortLookup( contentTab, sortKey )

    local lookup = {}

    for k, _ in pairs(contentTab) do

        lookup[#lookup+1] = k

    end

    table.sort( lookup, function(a, b ) return contentTab[a][sortKey] < contentTab[b][sortKey] end )

    return lookup

end

sortByName = buildSortLookup( tab, “name” )

sortByModel = buildSortLookup( tab, “model” )

sortByNum = buildSortLookup( tab, “num” )

local sortLookup = sortByNum

for i = 1,#sortLookup do

    local entry = tab[sortLookup[i]]

    print( entry.name )

end

That function is very helpful indeed. And yes, And yes, tables are the essence of Lua. I was just saying I will only use the type of  K,V tables only if I absolutely need to.

have you tried?

for i=1, #table do &nbsp; ...... end

This doesn’t work with this kind of table. It returns nothing.

&nbsp; &nbsp; for i=1,#table do &nbsp; &nbsp; &nbsp; &nbsp; print( table[i] ) ---\> nothing &nbsp; &nbsp; end

This does not work because you’re not creating a table with a numeric index but with the strings named “item1”, “item2” and so on. In this case, Lua uses a hash table for the table and so there’s no sorting available by nature of the data struct.

If you remove the string based key it’ll work as expected.

[lua]

local tab = {

    {name=“Item1”, num=1, model=5040},

    {name=“Item2”, num=2, model=5050},

    {name=“Item3”, num=3, model=5060},    

}

for i = 1,#tab do

    local entry = tab[i]

    print( entry.name )

end

[/lua]

Thanks for the reply.

I’m already familiar with the method you used, however, I still would like to use a table with key,value structure because at a certain point in my app I would like to access a specific key of that table and change one of its values. 

pairs is a slow operation and should be avoided… always process based on ordinal

If you always have a field name=“item1” etc. then, depending on how often you modify the table and how big your table is, a simple solution could be to just iterate over the table until you find the entry your looking for.

Another option is a second table used as a lookup for your current sort order.

[lua]

local tab = {

    item1 = {name=“Item1”, num=1, model=5040},

    item2 = {name=“Item2”, num=2, model=5050},

    item3 = {name=“Item3”, num=3, model=5060},    

}

local sortLookup = {

    “item3”,

    “item2”,

    “item1”,

}

for i = 1,#sortLookup do

    local entry = tab[sortLookup[i]]

    print( entry.name )

end

[/lua]

You’d have to keep both tables synchronized but that’s usually not a problem. This way you can also create sorting orders in whatever way you want without changing your original table.

@Michael Flad

Thanks a lot. that definitely solved my problem. I will always try in the future to keep my usage of key,value tables to a minimum. 

Glad this helped.

But you don’t need to minimize the usage of tables in general (of course depends on your project/size). They’re the very core data struct in Lua and in combination with the rest of the language a very flexible one too.

F.i. you could generate the lookup tables with a small function and do even complex sorting if required.

(had to paste the code without formatting as, somehow, all linefeed got lost)

local tab = {

    item1 = {name=“Item1”, num=4, model=6040},

    item2 = {name=“Item2”, num=6, model=5050},

    item3 = {name=“Item3”, num=5, model=4060},    

}

local function buildSortLookup( contentTab, sortKey )

    local lookup = {}

    for k, _ in pairs(contentTab) do

        lookup[#lookup+1] = k

    end

    table.sort( lookup, function(a, b ) return contentTab[a][sortKey] < contentTab[b][sortKey] end )

    return lookup

end

sortByName = buildSortLookup( tab, “name” )

sortByModel = buildSortLookup( tab, “model” )

sortByNum = buildSortLookup( tab, “num” )

local sortLookup = sortByNum

for i = 1,#sortLookup do

    local entry = tab[sortLookup[i]]

    print( entry.name )

end

That function is very helpful indeed. And yes, And yes, tables are the essence of Lua. I was just saying I will only use the type of  K,V tables only if I absolutely need to.