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

Just starting out? Need help? Post your questions and find answers here.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5614
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

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

Post 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
Last edited by Kwai chang caine on Thu Jan 22, 2026 6:56 pm, edited 1 time in total.
ImageThe happiness is a road...
Not a destination

PureBasic French Forum
threedslider
Enthusiast
Enthusiast
Posts: 547
Joined: Sat Feb 12, 2022 7:15 pm

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

Post 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
User avatar
NicTheQuick
Addict
Addict
Posts: 1558
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

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

Post 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.
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.
User avatar
jacdelad
Addict
Addict
Posts: 2062
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

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

Post 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...
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/2*DX517, 164TB+82TB+28TB+2TB SSD
Axolotl
Addict
Addict
Posts: 921
Joined: Wed Dec 31, 2008 3:36 pm

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

Post 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()) 
Last edited by Axolotl on Thu Jan 22, 2026 2:32 pm, edited 1 time in total.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
User avatar
NicTheQuick
Addict
Addict
Posts: 1558
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

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

Post 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
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.
User avatar
naf
User
User
Posts: 17
Joined: Fri Aug 18, 2023 3:19 pm
Location: Europe

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

Post by naf »

Look at

Code: Select all

PushListPosition()
PopListPosition()
User avatar
ChrisR
Addict
Addict
Posts: 1544
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

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

Post 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
User avatar
HeX0R
Addict
Addict
Posts: 1238
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

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

Post 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.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5614
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

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

Post 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)
ImageThe happiness is a road...
Not a destination

PureBasic French Forum
Post Reply