PDA

View Full Version : iterate through table in order



jon1977
March 17th, 2016, 05:04 PM
Hi,

Can anyone help?
I'm trying to sort a table of tables, iterating through them in order to send the data to Netremote.

I believe using the pairs funciton should work,
ipairs won't work as the index is not numerical
I can't easily generate the data with an incrementing numerical index as it is generated.
The data shows in the correct order in the variable inspector.

I have a functioning link to a google calendar, and I want to display a 3 month lookahead of calendar events on a netremote page.
Each table name is a date/time string with potentially multiple events if they have the same date and time.

e.g:
Given the following test data:



test = test or {}
test.Myevents = {

["20160314T000000Z"] = {[1] ="event1 14/03/2016 00:00:00"},
["20160520T000000Z"] = {[1] ="event2 20/05/2016 00:00:00"},
["20160311T000000Z"] = {[1] ="event3 11/03/2016 00:00:00"},
["20160522T000000Z"] = {[1] ="event4 22/05/2016 00:00:00"},
["20160527T000000Z"] = {[1] ="event5 27/05/2016 00:00:00"},
["20160308T000000Z"] = {[1] ="event6 08/03/2016 00:00:00", [2] ="event7 08/03/2016 00:00:00"},
["20160403T230000Z"] = {[1] ="event8 03/04/2016 23:00:00"},
["20160331T073000Z"] = {[1] ="event9 31/03/2016 07:30:00"},
["20160603T000000Z"] = {[1] ="event10 03/06/2016 00:00:00"},
["20160422T000000Z"] = {[1] ="event11 22/04/2016 00:00:00"},
["20160418T000000Z"] = {[1] ="event12 18/04/2016 00:00:00"},
["20160405T230000Z"] = {[1] ="event13 05/04/2016 23:00:00"},
["20160420T000000Z"] = {[1] ="event14 20/04/2016 00:00:00", [2] ="event15 20/04/2016 00:00:00"},
["20160624T000000Z"] = {[1] ="event16 24/06/2016 00:00:00"},
["20160514T000000Z"] = {[1] ="event17 14/05/2016 00:00:00"},
["20160329T000000Z"] = {[1] ="event18 29/03/2016 00:00:00"},
["20160629T230000Z"] = {[1] ="event19 29/06/2016 23:00:00"},
["20160505T230000Z"] = {[1] ="event20 05/05/2016 23:00:00"}
}


I used the following to try to iterate through it and update netremote, note, I try and sort the source table first:




local i, datetime, Nth, DaysEvents, TheEvent
i = 1
table.sort(test.Myevents)
for datetime, DaysEvents in pairs (test.Myevents) do
for Nth, TheEvent in pairs (DaysEvents) do
print(datetime.." "..Nth.." "..i..": "..TheEvent)
NetRemote.SetVariable("HOUSE.Calendar."..i..".name",TheEvent)
i = i + 1
end
end


but the sort does not work, the table names do not get sorted in order like they are in the variable inspector.
I've tried dropping out the T and Z letters to just have a number, and removing the " " to make the table name a number, but this does not work.

Is there a way to iterate through a table of sub tables, in alpha numerical order of sub table names?

Tieske8
March 18th, 2016, 11:06 AM
No you can't. You should create an extra table, or use the numerical part of the same table.

untested code top of my head;



local stable = {} -- sorted table, using an extra table here

for k,v in pairs(test.MyEvents) do
table.insert(stable, k) -- create an array like table, with the value being the key of the other table
end

-- table.sort works only on arrays and takes and extra parameter, the second
-- parameter is a function that return true/false based on a comparison
-- not needed here because the default will compare strings.
-- look it up in the Lua reference manual
table.sort(stable)

-- Now iterate the sorted list and fetch the data from the original table
for _, key in ipairs(stable) do
local mydata = test.MyEvents[key]

-- now here do something with mydata...

end

jon1977
March 20th, 2016, 02:14 PM
Thanks for that, works a treat!
I with the sub tables I also had to iterate in pairs through the ipairs iteration to extract the data
working code extract below if it helps anyone else.



local i
i = 0
local k, v
test.TheEventsSorted = {}
for k, v in pairs (test.TheEvents) do
table.insert(test.TheEventsSorted, k)
end
table.sort(test.TheEventsSorted)

local key, Nth, DaysEvents, TheEvent, _
for _, key in ipairs(test.TheEventsSorted) do
local DaysEvents = test.TheEvents[key]
for Nth, TheEvent in pairs (DaysEvents) do
print(Nth.." "..i..": "..TheEvent)
NetRemote.SetVariable("HOUSE.Calendar."..i..".name",TheEvent)
i = i + 1
end
end


Obvious when you know how.
With regards
Jon

Tieske8
March 21st, 2016, 12:04 PM
quick comment; the `for` statement creates the local variables used so the `local k,v` is not necessary, the same with second set of locals you create.