Page 1 of 1

Reading or writing inside a LIST() without move his current position [Resolved]

Posted: Thu Jan 22, 2026 1:55 pm
by Kwai chang caine
Hello at all

I suppose it's impossible to read a value in a list() without move current element
Like this :|

Code: Select all

Structure MyList
 a.s
 b.s
EndStructure

NewList ListChange.MyList()

For i = 1 To 5
 AddElement(ListChange())
 ListChange()\a = "Kcc" + Trim(Str(i))
 ListChange()\b = "PureBasic" + Trim(Str(i))
Next

ForEach ListChange() 
 
 CurrentElement = ListIndex(ListChange())
 Debug ListChange()\a
 
 If CurrentElement < ListSize(ListChange()) - 1
 
  SelectElement(ListChange(), CurrentElement + 1)
  Debug ListChange()\b + #CRLF$
  SelectElement(ListChange(), CurrentElement)
 
 EndIf 

Next
And i suppose too, writing is again worst :|

Have a good day

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 2:23 pm
by threedslider
Hello

Do you mean by that ? :

Code: Select all

Structure MyList
 a.s
 b.s
EndStructure

NewList ListChange.MyList()

For i = 1 To 5
 AddElement(ListChange())
 ListChange()\a = "Kcc" + Trim(Str(i))
 ListChange()\b = "PureBasic" + Trim(Str(i))
Next

ForEach ListChange() 
 
 CurrentElement = ListIndex(ListChange())
 Debug ListChange()\a
 
 If CurrentElement < ListSize(ListChange()) - 1
 
  SelectElement(ListChange(), CurrentElement )
  Debug ListChange()\b + #CRLF$
  ;SelectElement(ListChange(), CurrentElement)
 
 EndIf 

Next

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 2:29 pm
by NicTheQuick
Please don't work with ListIndex and SelectElement if it is not absolutely necessary. It is very slow compared to ChangeCurrentElement or a combination of PushListPosition and PopListPosition which I would prefer depending on what you wanna do.

Regarding the initial question: Yes, it is not possible to read directly from an element without changing the current element.
But you can use pointers to remember certain elements, read from and write to them while another element is the current one. Or you could use an array.

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 2:29 pm
by jacdelad
Depending on what exactly you want to do (and how you want to do it), you could either get the address of the element beforehand and work with it or use PushListPosition()/PopListPosition() to save and restore the current position.
Edit: Nick was a second faster...

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 2:31 pm
by Axolotl
Okay, there are (after all) various ways to remember the current list entry, make the change in the desired place, and make the remembered entry the current one.
In addition to your solution, there are two more...
(Or maybe I misunderstood you.)
Edit: Too slow... Now you can use this as an example of what was said above.

Code: Select all

 ; 1. Solution 
  *Old_Element = @mylist()   ; Get the address of the current element
  ; ..... do your stuff ..... 
  ChangeCurrentElement(mylist(), *Old_Element) ; Restore previous current element (from before the search)

  ; 2. Solution 
  PushListPosition(mylist())
  ; ..... do your stuff ..... 
  PopListPosition(mylist()) 

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 2:32 pm
by NicTheQuick
Here's an idea:

Code: Select all

Structure MyList
	a.s
	b.s
EndStructure

NewList ListChange.MyList()

For i = 1 To 5
	AddElement(ListChange())
	ListChange()\a = "Kcc" + Trim(Str(i))
	ListChange()\b = "PureBasic" + Trim(Str(i))
Next

Define *lastElement.MyList = FirstElement(ListChange())
While *lastElement And NextElement(ListChange())
	Debug *lastElement\a
	Debug ListChange()\b + #CRLF$
	*lastElement = @ListChange()	
Wend
Debug *lastElement\a

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 2:57 pm
by naf
Look at

Code: Select all

PushListPosition()
PopListPosition()

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 3:02 pm
by ChrisR
To work on a selected element while staying in the current index element, I often use this macro, borrowed from a Stargate code

Code: Select all

Structure StObject
  ObjectID.i
  Name.s
EndStructure

Global NewList Object.StObject()

Macro _ObjectID_(pObject, IDObject, ReturnProcedureValue = #False)
  PushListPosition(Object())
  Repeat
    ForEach Object()
      If Object()\ObjectID = IDObject
        pObject = @Object()
        PopListPosition(Object())
        Break 2
      EndIf
    Next
    Debug "_ObjectID_ Error: ObjectID = " + IDObject + " not found in Object List!"
    PopListPosition(Object())
    ProcedureReturn ReturnProcedureValue   ; with ProcedureReturn, it must be called from a Procedure
  Until #True
EndMacro

Procedure WorkOnSelectedObject(ObjectID)
  Protected *Object.StObject : _ObjectID_(*Object, ObjectID, #False)
  
  Debug ""
  Debug "Here In Procedure, you can work on the selected ObjectID element with *Object\xxxx or on the Current List element with Object()\xxxx"
  Debug "In Procedure *Object\ObjectID = " + *Object\ObjectID + " : *Object\Name = " + *Object\Name
  Debug "In Procedure Current Object() Index " + ListIndex(Object()) + " : Object()\ObjectID = " + Object()\ObjectID + " : Object()\Name = " + Object()\Name
  Debug ""  
EndProcedure

Name$ = "bla"
With Object()
  For i = 1 To 9
    AddElement(Object()) : \ObjectID = i : \Name= Name$ : Name$ + "Bla"
  Next
  
  SelectElement(Object(), 2)
  Debug "Main Current Index = " + ListIndex(Object()) + " : ObjectID = " + \ObjectID + " : Name = " + \Name
  
  WorkOnSelectedObject(6)
  
  Debug "Main Current Index = " + ListIndex(Object()) + " : ObjectID = " + \ObjectID + " : Name = " + \Name
EndWith

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 4:33 pm
by HeX0R
If you are only interested in the upcoming or previous element (like in your example), you could also use that approach:

Code: Select all

Procedure GetNeighborElements(*CurrentElement, *previous.INTEGER, *next.INTEGER)
	*previous\i = PeekI(*CurrentElement - SizeOf(INTEGER)) 
	*next\i     = PeekI(*CurrentElement - 2* SizeOf(INTEGER))
	If *previous\i
		*previous\i + 2* SizeOf(INTEGER)
	EndIf
	If *next\i
		*next\i + 2* SizeOf(INTEGER)
	EndIf
EndProcedure

Structure MyList
 a.s
 b.s
EndStructure

Define i, *NextElement.MyList, *PreviousElement.MyList

NewList ListChange.MyList()

For i = 1 To 5
 AddElement(ListChange())
 ListChange()\a = "Kcc" + Trim(Str(i))
 ListChange()\b = "PureBasic" + Trim(Str(i))
Next

ForEach ListChange() 
	GetNeighborElements(@ListChange(), @*PreviousElement, @*NextElement)
	Debug ListChange()\a
 	If *NextElement
 		Debug *NextElement\b
 	EndIf

Next
Not an official approach, though, but the position of those addresses never changed afaik.

Re: Reading or writing inside a LIST() without move his current position

Posted: Thu Jan 22, 2026 6:50 pm
by Kwai chang caine
First , thanks a lot at you all for your quicks answers :shock: 8)

@threedslider
I want just can read in a list without needed to pertubating the LIST :wink:
I think this function is missing :idea:
The result i wanted, i's the same i have given, but without change current element

Code: Select all

Kcc1
PureBasic2
NicTheQuick wrote:Regarding the initial question: Yes, it is not possible to read directly from an element without changing the current element.
That's what I was afraid of. :| Thank you for confirming that. 8)

@jacdelad and Axolotl and NAF
I didn't understand what this solution ChangeCurrentElement would be used for. ChangeCurrentElement and PushListPosition(mylist()) that JACELAD talk too, it's a little bit that i search but when even not as convenient to use as a direct reading at my advice
NicTheQuick wrote: Thu Jan 22, 2026 2:32 pm Here's an idea:
Waouhh !! it's exactely what i asked, can be read another element without all moving 8)
Nice peace of code, thanks

@CHRISR
Very nice code :shock: Perhaps a little bit complicated for my little head :oops:
I try to understand it, during all this week :wink: :mrgreen: :lol:
Thanks a lot too 8)

@HEXOR
Waooouh 2 :mrgreen: !!! very nice code, the pointers waltz :shock: 8)

Image
That's exactly what I was looking for, but not specifically for the before or after recording, but anywhere in the list :wink:
A style of

Code: Select all

MyElement$ = ReadElement(MyList(), 3)
WriteElement(MyList(), 3, "Kcc 2")

@FOR ALL
In fact it's the first time in more than 20 years i do PB, that i use the LIST() :oops:
Because i've always found this function heavy to use, compared to MAP and arrays

Firstly, this function addElement() forced to use for each adding :shock:
Why like the MAP we cannot record directly the element after the current element, without write again a line before ?
With MAP also there are the AddMapElement() but we can also adding an element directly with MyMap("New element") and it's magical the element is recorded, i love the map now that I finally understand them :oops:
The only one default, it's it is never natively sorted :|

Secondely, why it's impossible to read and again worst writing directly an element, without all moving ? :shock:
since the list never changes order, unlike the MAP, further more in the variable viewver there are a number ListLangage(0),ListLangage(1),2,3, etc

Image

so there are good a number for each element of the list :idea:
This wouldn't prevent other functions, certainly for more complex things I'm not aware of, but I find that I miss direct reading and writing., for have a simple code without X lines :|

Again thanks for all your nices codes and your advices
I wish to you all a very good end of day 8)