How to avoid empty array elements when making JSON out of structures?

Just starting out? Need help? Post your questions and find answers here.
Quin
Addict
Addict
Posts: 1122
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

How to avoid empty array elements when making JSON out of structures?

Post by Quin »

I have this code. It works as expected, accept the generated JSON has one more item in the array than I'd expect, an empty string. Is this because of how PureBasic's Dim/ReDim keywords work? If so, is there a way around it?

Code: Select all

EnableExplicit

Structure JSON
Array Test$(0)
EndStructure

Global NewList Names$()
AddElement(Names$()) : Names$() = "Quin"
AddElement(Names$()) : Names$() = "Sam"
AddElement(Names$()) : Names$() = "Malia"

Define j.JSON, Size.i
ForEach Names$()
Size = ArraySize(j\Test$()) + 1
ReDim j\Test$(Size)
j\Test$(Size - 1) = Names$()
Next
Define JSONID.i = CreateJSON(#PB_Any)
InsertJSONStructure(JSONValue(JSONID), @j, JSON)
Debug ComposeJSON(JSONID)
FreeJSON(JSONID)
Andesdaf
User
User
Posts: 83
Joined: Sun Mar 22, 2009 2:53 pm
Location: GER, Saxony

Re: How to avoid empty array elements when making JSON out of structures?

Post by Andesdaf »

Yes it's because ReDim(Size) creates Size+1 elements. You could ReDim with Size-1 in the end or do the first ReDim only in the second iteration of the ForEach loop:

Code: Select all

Define j.JSON, Size.i
Size = ArraySize(j\Test$())
ForEach Names$()
  If ListIndex(Names$()) > 0
    Size + 1
    ReDim j\Test$(Size)
  EndIf
  j\Test$(Size) = Names$()
Next
but that is only safe if the array is initially empty.
Quin
Addict
Addict
Posts: 1122
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: How to avoid empty array elements when making JSON out of structures?

Post by Quin »

Andesdaf wrote: Thu Apr 24, 2025 8:58 pm Yes it's because ReDim(Size) creates Size+1 elements. You could ReDim with Size-1 in the end or do the first ReDim only in the second iteration of the ForEach loop:

Code: Select all

Define j.JSON, Size.i
Size = ArraySize(j\Test$())
ForEach Names$()
  If ListIndex(Names$()) > 0
    Size + 1
    ReDim j\Test$(Size)
  EndIf
  j\Test$(Size) = Names$()
Next
but that is only safe if the array is initially empty.
I know the array will always be empty, I explicitly check for that, so that's okay.
Thanks for your help, this works!
User avatar
NicTheQuick
Addict
Addict
Posts: 1503
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: How to avoid empty array elements when making JSON out of structures?

Post by NicTheQuick »

It's not a good idea to constantly use ReDim in each iteration. When there are a lot of elements in the LinkedList ReDim is called on each element which means that in the background a lot of copying is be done in the worst case. Don't do that.
Just ReDim once before the loop and use a variable to iterate through the indexes:

Code: Select all

EnableExplicit

Structure JSON
	Array Test$(0)
EndStructure

Global NewList Names$()
AddElement(Names$()) : Names$() = "Quin"
AddElement(Names$()) : Names$() = "Sam"
AddElement(Names$()) : Names$() = "Malia"

Define j.JSON, i.i = 0
ReDim j\Test$(ListSize(Names$()) - 1)
ForEach Names$()
	j\Test$(i) = Names$()
	i + 1
Next
Define JSONID.i = CreateJSON(#PB_Any)
InsertJSONStructure(JSONValue(JSONID), @j, JSON)
Debug ComposeJSON(JSONID)
FreeJSON(JSONID)
For some reason this also works if there are no elements in the LinkedList although ReDim should throw an error because it is called with a negative size. :?:

Edit: FYI: I created another topic regarding the size of -1 here: https://www.purebasic.fr/english/viewtopic.php?t=86812
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Post Reply