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

Find quick help here to get you started with Hollywood
Post Reply
GMKai
Posts: 136
Joined: Mon Feb 15, 2010 10:58 am

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

Post 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?
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

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

Post 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".
I'm on registered MorphOS using FlowStudio.
User avatar
airsoftsoftwair
Posts: 5425
Joined: Fri Feb 12, 2010 2:33 pm
Location: Germany
Contact:

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

Post by airsoftsoftwair »

Don't know what the problem here is either... what do you mean by the "check for the columns"?
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

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

Post 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?
I'm on registered MorphOS using FlowStudio.
GMKai
Posts: 136
Joined: Mon Feb 15, 2010 10:58 am

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

Post 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.
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

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

Post 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().
I'm on registered MorphOS using FlowStudio.
User avatar
airsoftsoftwair
Posts: 5425
Joined: Fri Feb 12, 2010 2:33 pm
Location: Germany
Contact:

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

Post 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.
GMKai
Posts: 136
Joined: Mon Feb 15, 2010 10:58 am

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

Post 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?
User avatar
airsoftsoftwair
Posts: 5425
Joined: Fri Feb 12, 2010 2:33 pm
Location: Germany
Contact:

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

Post 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
Post Reply