How to optimise out FindLink() from Eachin loop?

BlitzMax Forums/BlitzMax Programming/How to optimise out FindLink() from Eachin loop?

For b:blah = EachIn blahlist
	bLink:TLink = blahlist.FindLink(b)
Next

Is there anyway to get rid of the FindLink()? Hacking into EachIn maybe to get the current TLink object?

Use the TListEnumerator

This way you can iterate through the TLink construction instead iterating through the values

I'll just have to use a While loop instead. Easy answer.

Type List Extends TList
	Field Enum:TListEnum

	Method ObjectEnumerator:TListEnum()
		enum=New TListEnum
		enum._link=_head._succ
		Return enum
	End Method

	Method CurrentLink:TLink()
		Return enum._link._pred
	End Method
End Type


;)

I'd leave it at using it for reading data, not modifying _pred/ _succ handles. I've tried. it didn't work very well. I wrote my own different style list:

Strict

Framework brl.blitz
Import brl.linkedlist
Import brl.standardio

Type Node
	Field Nxt:node, Prv:node
	Field Value:Object
	Field Parent:Group

	Method MoveFirst()
		If parent.head=Self Then Return
		If parent.tail=Self Then
			parent.tail=prv
		Else
			prv.nxt=nxt
			nxt.prv=prv
			prv=parent.tail
			nxt=parent.head
		EndIf
		parent.head=Self
	End Method
	
	Method MoveLast()
		If parent.Tail=Self Then Return
		If parent.head=Self Then
			parent.head=nxt
		Else
			prv.nxt=nxt
			nxt.prv=prv
			prv=parent.tail
			nxt=parent.head
		EndIf
		parent.tail=Self
	End Method
	
	Method Move(g:group)
		If prv Then prv.nxt=nxt
		If nxt Then nxt.prv=prv
		If g.head Then g.head.prv=Self
		If g.tail Then g.tail.nxt=Self
		nxt=g.head
		prv=g.tail
		parent=g
		If g.head=Null Then g.head=Self
		g.tail=Self
	End Method
End Type

Rem test
Local g:group=New group
g.AddLast("Function poo")
g.AddLast(" Print ~qhi~q")
g.AddLast("Function hi")
g.AddLast("End Function")
g.AddLast("End Function")

For Local n:node=EachIn g
'	Print String(n.Value)
	If (String(n.Value))[0..8]="Function" Then g.Startnewgroup(g.enum.current,(String(n.Value))[9..])
	If (String(n.Value))[0..12]="End Function" Then g.EndGroup(g.enum.current)
Next

For Local g2:node=EachIn g
	If group(g2) Then
		For Local n:node=EachIn group(g2)
			If group(n) Then
			Else
				Print String(n.value)
			EndIf
		Next
	Else
		Print String(g2.value)
	EndIf
Next
EndRem

Type Group Extends Node
	Field Head:node, Tail:node
	Field Enum:GroupEnum	
	Field s:stack
	
	Function FromArray:Group(o:Object[], val:Object=Null)
		Local g:group=New group
		g.value=val
		Local n:node=New node,pn:node=n
		g.Head=n
		n.Value=o[0]
		n.parent=g
		For Local i=1 Until o.length
			n:node=New node
			n.parent=g
			n.Value=o[i]
			pn.Nxt=n
			n.Prv=pn
			pn=n
		Next
		g.Tail=n
		n.nxt=g.Head
		Return g
	End Function
	
	Function FromTList:Group(l:TList, val:Object=Null)
		Local g:group=New group
		g.value=val
		Local n:node=New node, pn:node=n
		g.head=n
		Local o:Object
		For o=EachIn l
			n.parent=g
			n.Value=o
			pn.nxt=n
			n.prv=pn
			pn=n
			n:node=New node
		Next
		n.parent=g
		n.Value=o
		pn.nxt=n
		n.prv=pn
		g.Tail=n
		n.nxt=g.head
		Return g
	End Function

	Method New()
		s=New Stack
	End Method

	Method Delete()
		Remove
		Head.nxt=Null
		Head.prv=Null
		Tail.nxt=Null
		Tail.prv=Null
		Head=Null
		Tail=Null
	End Method
	
	Method Contains(val:Object)
		Local t:GroupEnum=enum
		enum=Null
		For Local n:node=EachIn Self
			If n.Value=val Then Return 1
		Next
		enum=t
		Return 0
	End Method
	
	Method Remove()
		For Local n:Node=EachIn Self
			n.prv.nxt=Null
			n.prv=Null
		Next
	End Method
	
	Method First:Node()
		Return head
	End Method
	
	Method Last:Node()
		Return tail
	End Method
	
	Method AddLast:Node(val:Object)
		Local n:node=New node
		n.value=val
		n.move(Self)
		Return n
	End Method
	
	Method AddFirst:Node(val:Object)
		Local n:node=New node
		n.value=n
		n.move(Self)
		n.movefirst()
		Return n
	End Method
	
	Method Startnewgroup(n:node, val:Object=Null)
		Local gs:GroupStarter=New GroupStarter
		gs.v=val
		gs.n=n
		s.Push(gs)
	End Method
	
	Method EndGroup:Group(n:node)
		Local gs:groupstarter=groupstarter(s.pop())
		Return GroupRange(gs.n,n,gs.v)
	End Method
	
	Method GroupRange:group(start:node,en:node, val:Object=Null)
		start.prv.nxt=en.nxt
		en.nxt.prv=start.prv
		Local g:group=New group
		start.prv=en
		If en=enum.current Then If enum.current.nxt<>Null Then enum.current=enum.current.nxt Else enum.current=Null
		en.nxt=start
		g.head=start
		g.tail=en
		g.move(Self)
		Return g
	End Method
	
	Method ObjectEnumerator:GroupEnum()
		If enum=Null Then
			Enum=GroupEnum.Create(Self)
		ElseIf 0=Enum.HasNext() Then
			Enum=GroupEnum.Create(Self)
		EndIf
		Return Enum
	End Method
End Type

Type GroupStarter
	Field v:Object,n:node
End Type

Type GroupEnum
	Field gr:group
	Field Current:Node
	Field qwerty:Byte
	
	Function Create:GroupEnum(g:group)
		Local ge:groupenum=New groupenum
		ge.gr=g
		If g.head<>Null Then ge.Current=g.head
		Return ge
	End Function
	
	Method HasNext()
		If current Then Return Current.nxt<>gr.head Else Return 0
	End Method
	
	Method NextObject:Object()
		If current<>gr.head Then current=current.nxt ElseIf qwerty Then current=current.nxt Else qwerty=1
		Return current
	End Method
End Type

'LIFO stack
Type Stack
	Field frst:StackElement
	
	Method Push(v:Object)
		Local se:stackelement=New stackelement
		se.nxt=frst
		se.value=v
		frst=se
	End Method
	
	Method Pop:Object()
		Local t:Object=frst.Value
		frst=frst.nxt
		Return t
	End Method
End Type

Type StackElement
	Field nxt:StackElement
	Field Value:Object
End Type


Enum is public, so just access Enum.Current.

Thanks bot. That works nicely.