Page 1 of 2
Prefilling a List
Posted: Sun Dec 24, 2023 7:05 pm
by jchase1970
Is there a way to take a set of information and create the list directly with it without using the addelement command
For example,
I have a set of numbers 1,2,3,4,5,8,9,11,15,17,19,45,65,78 and so on could be a really big set
I want to have them all in a searchable list or other item like an array is fine too
Is there a way I can say list="1,2,3,4,5,8,9,11,15,17,19,45,65,78" to create the list predefined?
Over having to have all the addelement commands?
Re: Prefilling a List
Posted: Sun Dec 24, 2023 7:19 pm
by Quin
Nope. It's incredibly unfortunate, but I also highly doubt it will ever be added due to the attitudes of many users (and maybe the PB devs themselves) about syntax sugar.
Re: Prefilling a List
Posted: Sun Dec 24, 2023 7:19 pm
by Paul
Maybe something like this?
Code: Select all
set.s="[1,2,3,4,5,8,9,11,15,17,19,45,65,78]"
NewList myset()
ParseJSON(0, set)
ExtractJSONList(JSONValue(0), myset())
ForEach myset()
Debug myset()
Next
Re: Prefilling a List
Posted: Sun Dec 24, 2023 7:28 pm
by skywalk
I agree, this has been requested many times.
But why add a syntax case for an extremely simple case?
I rarely have lists or maps of single elements.
I have an init() function for most of my apps.
It is no big deal with cut and paste.

Re: Prefilling a List
Posted: Sun Dec 24, 2023 7:36 pm
by jchase1970
skywalk, how do you add hundreds of items to a list, is it really a long section of code filled with,
AddElement(MyList())
MyList() = x
This is so inefficient, ugly and bloating code, even with copy and pasting.
I just can't believe there is not a easy way to create a list of data.
Re: Prefilling a List
Posted: Sun Dec 24, 2023 7:49 pm
by skywalk
You use a loop construct for the list loads.
The cut and paste I'm referring is where you enter your fixed values?
They can be in a csv or a datasection or even a SQLite database.
Code: Select all
ResetList(llTPS())
nPts = GetYourData(d())
If nPts > 1
For i = 0 To nPts - 1
AddElement(llTPS())
llTPS() = d(i)
Next i
EndIf
Re: Prefilling a List
Posted: Sun Dec 24, 2023 8:00 pm
by jchase1970
skywalk,
The solution I am using is storing the info in Data statements and doing I think basically what you are saying
For l=1 To 40
Read a
AddElement(set())
set() = a
Next
Re: Prefilling a List
Posted: Sun Dec 24, 2023 8:02 pm
by skywalk
Yes, that is one way.
But, your data is hardcoded to your exe.
If your data changes or grows, better to use external files or databases.
Re: Prefilling a List
Posted: Sun Dec 24, 2023 10:09 pm
by Oso
I often tend to favour the use of maps rather than lists, partly because they are so much easier to populate, with a single statement, but I also find them easier to manage. I've always found lists to be a bit arcane. But it depends on performance considerations and the below may not suit everyone — it works for certain tasks, but not if sorting sequence is a factor.
Code: Select all
EnableExplicit
NewMap List()
List("10")
List("12")
List("18")
List("25")
ForEach List()
Debug MapKey(List())
Next
Re: Prefilling a List
Posted: Mon Dec 25, 2023 12:44 am
by DeanH
I do this old-school by brute force with a set of procedures.
I use lists when a key is not required, and maps when keys are useful.
Lists can be sorted as well.
Code: Select all
;This procedure adds an integer value to a list, optionally at a specified position
Procedure ListAddn(List tempb.i(), value.i , position=-1)
Protected top
top=ListSize(tempb())
If pos>top Or position=-1
AddElement(tempb())
tempb()=value
ProcedureReturn
EndIf
SelectElement(tempb(), position)
InsertElement(tempb())
tempb()=value
EndProcedure
;Add a string value to a list only if the value is not in the list
Procedure.i ListAddS(List temp$(), value$, checkcase=#True)
Protected added, lookfor$, found, a$
If value$
;check to see if value$ is already in list temp$()
lookfor$=value$
If checkcase
lookfor$=LCase(lookfor$)
EndIf
ForEach temp$()
a$=temp$()
If checkcase
a$=LCase(a$)
EndIf
If lookfor$=a$
found=#True
Break
EndIf
Next
If found=#False
AddElement(temp$())
temp$()=value$
added=#True
EndIf
ResetList(temp$())
EndIf
ProcedureReturn added
EndProcedure
Procedure.i MakeList(List mylist.i(),listtoadd$)
Protected n, i, a$
n=CountString(listtoadd$, ",")+1
For i=1 To n
a$=StringField(listtoadd$, i, ",")
ListAddn(mylist(), Val(a$))
Next
ProcedureReturn n
EndProcedure
NewList TestList.i()
alist$="2,8,11,4,78,5,3,9,1,19,14,19,65,45"
MakeList(TestList(),alist$)
SortList(TestList(),#PB_Sort_Ascending)
ForEach TestList()
Debug TestList()
Next
End
I was not able to get the JSON example to work within a procedure (below). Error report is "A JSON value of type array is expected".
Procedure MakeList(List mylist(), set$)
CreateJSON(0)
ParseJSON(0, set$)
ExtractJSONList(JSONValue(0), mylist()) ;error on this line
FreeJSON(0)
EndProcedure
Re: Prefilling a List
Posted: Mon Dec 25, 2023 1:34 am
by Olli
Is it ok ?
(this syntax :
myMacro(arg1 arg2 arg3 ...)
)
Code: Select all
Macro quote()
"
EndMacro
Macro listSplit(arg)
tmp$ = quote()arg#quote()
For privateI = 1 To CountString(tmp$, " ") + 1
AddElement(*currentList\x() )
*currentList\x() = Val(StringField(tmp$, privateI, " ") )
Next
EndMacro
Structure myList
List x.i()
EndStructure
Global *currentList.myList
Procedure myListCreate()
Protected *this.myList = AllocateMemory(SizeOf(myList) )
InitializeStructure(*this, myList)
*currentList = *this
ProcedureReturn *this
EndProcedure
Define *x.myList = myListCreate()
listSplit(1 2 4 8 16 32)
ForEach(*x\x() )
Debug *x\x()
Next
Re: Prefilling a List
Posted: Mon Dec 25, 2023 1:56 am
by AZJIO
You are using unnecessary garbage in your code. If it seems to you that it is easier to write this way, but this does not mean that it is good for the program.
Code: Select all
EnableExplicit
; https://www.purebasic.fr/english/viewtopic.php?f=12&t=65159&p=486382&hilit=SplitL#p486382
Procedure SplitL(String.s, List StringList.s(), Separator.s = " ")
Protected S.String, *S.Integer = @S
Protected.i p, slen
slen = Len(Separator)
ClearList(StringList())
*S\i = @String
Repeat
AddElement(StringList())
p = FindString(S\s, Separator)
StringList() = PeekS(*S\i, p - 1)
*S\i + (p + slen - 1) << #PB_Compiler_Unicode
Until p = 0
*S\i = 0
EndProcedure
Global NewList NumStr.s()
Global NewList Num.i()
Global s$ = "1,2,3,4,5,8,9,11,15,17. ,19,45,65,78"
SplitL(s$, NumStr(), ",")
ForEach NumStr()
If AddElement(Num())
Num() = Val(NumStr())
EndIf
Next
FreeList(NumStr())
ForEach Num()
Debug Num()
Next
Re: Prefilling a List
Posted: Thu Dec 28, 2023 4:21 pm
by ebs
DeanH wrote: Mon Dec 25, 2023 12:44 am
I was not able to get the JSON example to work within a procedure (below). Error report is "A JSON value of type array is expected".
Procedure MakeList(List mylist(), set$)
CreateJSON(0)
ParseJSON(0, set$)
ExtractJSONList(JSONValue(0), mylist()) ;error on this line
FreeJSON(0)
EndProcedure
This works fine:
Code: Select all
set.s = "[1,2,3,4,5,8,9,11,15,17,19,45,65,78]"
NewList myset()
Procedure MakeList(List mylist(), set.s)
CreateJSON(0)
ParseJSON(0, set)
ExtractJSONList(JSONValue(0), mylist())
FreeJSON(0)
EndProcedure
MakeList(myset(), set)
ForEach myset()
Debug myset()
Next
Re: Prefilling a List
Posted: Thu Dec 28, 2023 4:52 pm
by Marc56us
AddElement(MyList())
MyList() = x
This is so inefficient, ugly and bloating code, even with copy and pasting.
But a compiler doesn't think and work like a human: it's often much faster for it to repeat simple assignment instructions than to perform calculations.
How many instructions in ASM or C to do this like that rather than other solutions (i.e Json) ?
(I don't know, but I think only two instructions per variable ?)
Code: Select all
NewList myset()
AddElement(myset()) : myset() = 1
AddElement(myset()) : myset() = 2
AddElement(myset()) : myset() = 3
AddElement(myset()) : myset() = 4
AddElement(myset()) : myset() = 5
AddElement(myset()) : myset() = 8
AddElement(myset()) : myset() = 9
AddElement(myset()) : myset() = 11
AddElement(myset()) : myset() = 15
AddElement(myset()) : myset() = 17
AddElement(myset()) : myset() = 19
AddElement(myset()) : myset() = 45
AddElement(myset()) : myset() = 65
AddElement(myset()) : myset() = 78
For those sort of code, I do one line
AddElement(myset()) : myset() =
and press CTRL + D x time, then edit end of lines
Fast
Easy to read

And you can use
Macros if you don't want to clutter up your code (in which case the code will be written at the last minute).
And If there were hundreds of values, then I'd use "Read Data", simply because it's readable too.

Always keep in mind that you may have to modify a code several months or years later.

Re: Prefilling a List
Posted: Thu Dec 28, 2023 5:09 pm
by AZJIO
Marc56us wrote: Thu Dec 28, 2023 4:52 pm
and press CTRL + D
replace the comma with #CRLF$ + AddElement(myset()) : myset() =
If the JSON engine is built into the program initially, then you can use it, but for the sake of a small list, I would not embed a third-party module.