Page 1 of 1

How to iterate correctly over a given table and peek specific values

Posted: Tue Jan 12, 2021 2:49 pm
by GMKai

Code: Select all

OpenFile(1, "t:table.bin", #MODE_READ)
  newtable = ReadTable(1)
CloseFile(1)

Function p_iteratelist(table)
   Local counter = 0
   If(HaveItem(table,"stations"))
      counter = TableItems(table.stations)
      DebugPrint("Stations: "..counter)
      If(counter> 0)
         For i,v In IPairs(table.stations)
           DebugPrint("i: "..i)
           ForEach(v, DebugPrint)
           DebugPrint("Open: "..HaveItem(v,"isOpen"))
           DebugPrint("PLZ: "..HaveItem(v,"postCode"))
    
        Next
      EndIf()
   Else
      counter = 0
   EndIf()
EndFunction

p_iteratelist(newtable)    

The code above gives this output:

Code: Select all

Und Action!
Stations: 6
i: 0
brand Freie Tankstelle
isOpen 1
postCode 48653
dist 0.2
place Coesfeld
lat 51.94431
street Münsterstraße
lng 7.1713185
name City Tank Coesfeld
id bc7702f4-9ddb-4d3f-b4c8-7a9f5e3eca25
price 1.409
houseNumber 53
Open: 0
PLZ: 0
i: 1
brand STAR
isOpen 1
postCode 48653
dist 0.9
place Coesfeld
lat 51.93744
street Dülmener Straße
lng 7.167851
name star Tankstelle
id 005056ba-7cb6-1ed2-bceb-b34cf7408d48
price 1.409
houseNumber 22
Open: 0
PLZ: 0
i: 2
brand freie Tankstelle
isOpen 1
postCode 48653
dist 1.2
place Coesfeld
lat 51.934755
street Dülmener Str.
lng 7.168276
name Stefan von Bronk
id 302db304-457a-42b6-c9d6-55271cfe7d8b
price 1.409
houseNumber 42
Open: 0
PLZ: 0
i: 3
brand Westfalen
isOpen 1
postCode 48653
dist 0.9
place Coesfeld
lat 51.95288
street Holtwicker Str.
lng 7.16396
name Sascha Trieburg
id 9d5ad5db-6db4-41d2-8a1d-6745d5002ff1
price 1.419
houseNumber 31
Open: 0
PLZ: 0
i: 4
brand Westfalen
isOpen 1
postCode 48653
dist 1
place Coesfeld
lat 51.93675
street Dülmener Str.
lng 7.16796
name Sascha Triburg
id b985be53-5be2-4a2e-b0f4-cf8c03fc3881
price 1.419
houseNumber 24-26
Open: 0
PLZ: 0
i: 5
brand Q1
isOpen 1
postCode 48653
dist 1.7
place Coesfeld
lat 51.9351
street Rekener Straße
lng 7.15223
name Q1 Tankstelle
id b67bdf8b-a03a-4f26-abb4-f99eff80e1a3
price 1.419
houseNumber 92
Open: 0
PLZ: 0
https://www.dropbox.com/s/g7amyznqy9lb7 ... e.bin?dl=0
How come the table the check for the columns gives 0, whereas the DebugPrint finds these values?

Re: How to iterate correctly over a given table and peek specific values

Posted: Tue Jan 12, 2021 5:51 pm
by SamuraiCrow
If you need all keys for a table regardless of order, try switching from IPairs to Pairs. I don't know if this solves your problem because I really don't see the problem nor any mention in your example of "columns".

Re: How to iterate correctly over a given table and peek specific values

Posted: Tue Jan 12, 2021 10:34 pm
by airsoftsoftwair
Don't know what the problem here is either... what do you mean by the "check for the columns"?

Re: How to iterate correctly over a given table and peek specific values

Posted: Wed Jan 13, 2021 1:12 am
by SamuraiCrow
On second thought, I think I know what you're trying to do.

Code: Select all

OpenFile(1, "t:table.bin", #MODE_READ)
  newtable = ReadTable(1)
CloseFile(1)

Function p_iteratelist(table)
   If(HaveItem(table,"stations"))
      DebugPrint("Stations: "..counter)
      For i,v In IPairs(table.stations)
         If(i > 0)
           DebugPrint("i: "..i)
           ForEach(v, DebugPrint)
           DebugPrint("Open: "..HaveItem(v,"isOpen"))
           DebugPrint("PLZ: "..HaveItem(v,"postCode"))
         EndIf
     Next
   EndIf
EndFunction

p_iteratelist(newtable)    
Is this what you meant?

Re: How to iterate correctly over a given table and peek specific values

Posted: Thu Jan 14, 2021 3:37 pm
by GMKai
Hi there,

this code should make clearer what point is open:

Code: Select all

OpenFile(1, "t:table.bin", #MODE_READ)
  newtable = ReadTable(1)
CloseFile(1)

Function p_iteratelist(table)
   Local counter = 0
   If(HaveItem(table,"stations"))
      counter = TableItems(table.stations)
      DebugPrint("Stations: "..counter)
      If(counter> 0)
         For i,v In Pairs(table.stations)
           DebugPrint("--------")
           DebugPrint("i: "..i)
           ForEach(v, DebugPrint)
           DebugPrint("Open: "..HaveItem(v,"isOpen"))
           DebugPrint("PLZ: "..HaveItem(v,"postCode"))
           ;this needs to work:
           ;DebugPrint(v.isOpen)
        Next
      EndIf()
   Else
      counter = 0
   EndIf()
EndFunction

p_iteratelist(newtable)    
Gives this log:

Code: Select all

--------
i: 1
brand STAR
isOpen 1
postCode 48653
dist 0.9
place Coesfeld
lat 51.93744
street Dülmener Straße
lng 7.167851
name star Tankstelle
id 005056ba-7cb6-1ed2-bceb-b34cf7408d48
price 1.409
houseNumber 22
Open: 0
PLZ: 0
--------
i: 2
brand freie Tankstelle
isOpen 1
postCode 48653
dist 1.2
place Coesfeld
lat 51.934755
street Dülmener Str.
lng 7.168276
name Stefan von Bronk
id 302db304-457a-42b6-c9d6-55271cfe7d8b
price 1.409
houseNumber 42
Open: 0
PLZ: 0
--------
You see a printed table with index "postCode" and index "isOpen".
At the same time, HaveItem claims these keys do not exist.

Re: How to iterate correctly over a given table and peek specific values

Posted: Fri Jan 15, 2021 6:37 pm
by SamuraiCrow
Just to narrow it down, try switching from HaveItem() to RawGet(). If it's truly not there, RawGet() will return Nil. It may just be a weird bug in HaveItem().

Re: How to iterate correctly over a given table and peek specific values

Posted: Mon Jan 18, 2021 10:37 pm
by airsoftsoftwair
GMKai wrote:
Thu Jan 14, 2021 3:37 pm
You see a printed table with index "postCode" and index "isOpen".
At the same time, HaveItem claims these keys do not exist.
Probably related to the fact that HaveItem() converts all keys to lower case. As stated in the docs:
Note that if you pass a string in the key parameter, it will be converted to lower case automatically. If you don't want that, use RawGet() instead.
So, as SamuraiCrow suggested, try RawGet() instead, or, as a better idea, use lower case only when using strings as table keys.

Re: How to iterate correctly over a given table and peek specific values

Posted: Wed Jan 20, 2021 1:04 pm
by GMKai

Code: Select all

Function p_iteratelist(table)
   Local counter = 0
   If(HaveItem(table,"stations"))
      counter = TableItems(table.stations)
      DebugPrint("Stations: "..counter)
      If(counter> 0)
         For i,v In Pairs(table.stations)
           DebugPrint("--------")
           DebugPrint("i: "..i)
           Local myOpen = RawGet(v,"isOpen")
           Local myplz = RawGet(v,"postCode")
           DebugPrint("Open: "..myOpen.." PLZ: "..myplz)
        Next
      EndIf()
   Else
      counter = 0
   EndIf()
EndFunction
Thank you guys,
the above function does work for me.
I will have to see what happens, when RawGet fails and another question:

Why does HaveItem() have to change keys to lowercase?

Re: How to iterate correctly over a given table and peek specific values

Posted: Fri Jan 22, 2021 12:31 am
by airsoftsoftwair
GMKai wrote:
Wed Jan 20, 2021 1:04 pm
Why does HaveItem() have to change keys to lowercase?
It's because string table indices are case sensitive in Hollywood. To hide that fact from the user, HaveItem() will convert the string to lower case because obviously the user expects that HaveItem(t, "test") and HaveItem(t, "TEST") refer to the same table item because t.test and t.TEST refer to the same item as well. That's why HaveItem() behaves like it does. For people really needing case sensitive access, there's RawGet().

Full story here: viewtopic.php?f=33&t=2963