[TListEx] Indexbasierte Zugriffe (ähnlich wie bei arrays)

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Trust

Betreff: [TListEx] Indexbasierte Zugriffe (ähnlich wie bei arrays)

BeitragMi, Jan 24, 2018 14:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Leute,

um bei TLists die selben Vorteile wie bei Arrays, nämlich Zugriff auf Elemente über einen Index zu haben, ist die Klasse "TListEx" mit folgenden fünf relevanten Methoden entstanden.

Fügt der Liste ein Objekt hinzu
- value:Object: Ein BMax-Objekt das hinzugefügt werden soll
- pIndex:Int: Der index(position) an dem das Objekt hinzugefügt werden soll
- Return: Gibt den TLink des Objekts zurück
Arrow Push:TLink( value:Object, pIndex:Int )

Gibt ein Objekt aus der Liste zurück, das Objekt wird dabei aus der Liste gelöscht
- pIndex:Int: Der index(position) an dem sich das Objekt in der Liste befindet
- Return: Das BMax-Object
Arrow Pop:Object( pIndex:Int )

Wie die Methode "Push", nur dass das Objekt nicht hinzugefügt wird,
sondern ein bestehendes Objekt an der Position pIndex mit diesem Objekt ersetzt wird
- value:Object: Ein BMax-Objekt das hinzugefügt werden soll
- pIndex:Int: Der index(position) an dem das Objekt hinzugefügt werden soll
- Return: Gibt den TLink des Objekts zurück
Arrow ToList:TLink( value:Object, pIndex:Int )

Wie die Methode "Pop", nur dass das Objekt nicht aus der Liste entfernt wird
- pIndex:Int: Der index(position) an dem sich das Objekt in der Liste befindet
- Return: Das BMax-Object
Arrow FromList:Object( pIndex:Int )

Gibt den Index des übergebenen Objekts zurück
- value:Object: Das Objekt, dessen Index man haben möchte
- Return: Der Index an dem sich das Objekt befindet oder Null, falls kein Objekt gefunden wurde
Arrow Index:Int(value:Object)


BlitzMax: [AUSKLAPPEN]
Type TListEx Extends TList
Field _count:Int = 0

' ######### Overriding BMax's TList Methods #########


' This Count Method is incredibly faster than the original Count-Method
Method Count:Int()
Return Self._count
End Method


' The Methods AddFirst/AddLast are internally calling InsertBeforeLink/InsertAfterLink so they don't need to be overridden

' Add Objects
Method InsertBeforeLink:TLink( value:Object, succ:TLink )
Local link:TLink = Super.InsertBeforeLink( value, succ )
If link Then _count:+1
Return link
End Method

Method InsertAfterLink:TLink( value:Object, pred:TLink )
Local link:TLink = Super.InsertAfterLink( value, pred )
If link Then _count:+1
Return link
End Method


' Remove Objects
Method RemoveFirst:Object()
Local obj:Object = Super.RemoveFirst()
If obj Then _count:-1
Return obj
End Method

Method RemoveLast:Object()
Local obj:Object = Super.RemoveLast()
If obj Then _count:-1
Return obj
End Method

Method Remove( value:Object )
Local success:Int = Super.Remove( value )
If success Then _count:-1
End Method


' ######### New Methods/Functions #########

' This function is used internally
Function _NextLink:Int( link:TLink Var )
If link._succ._value <> link._succ
link = link._succ
Return True
EndIf
Return False
End Function

' Add an object at the given index
Method Push:TLink( value:Object, pIndex:Int )
Local newLink:TLink = New TLink, i:Int = 1
Assert value Else "Can't insert Null object into list"
Local listCount:Int = Self.Count()

' Get head of list
Local objLink:TLink = Self._head

If pIndex > listCount
Return Self.AddLast(value)
ElseIf pIndex <= 1
Return Self.AddFirst(value)
Else

While _NextLink( objLink )
If i = pIndex Then

' Assign object to Link
newLink._value = value

' The new object will be inserted before obj, so the new object gets the index of obj
' and obj gets the index of pIndex+1 and so on...

' Connect new link with its previous and next nodes
newLink._succ = objLink
newLink._pred = objLink._pred

' Connect newLink's next node with newLink
objLink._pred._succ = newLink
' Connect newLink's previous node with newLink
objLink._pred = newLink

_count:+1
Return newLink
EndIf
i :+ 1
Wend
EndIf
End Method

' Get and remove an object from the list at the given index
Method Pop:Object( pIndex:Int )
Local obj:Object, i:Int = 1
Local listCount:Int = Self.Count()

' Get head of List
Local objLink:TLink = Self._head

If pIndex >= listCount
Return Self.RemoveLast()
ElseIf pIndex <= 1
Return Self.RemoveFirst()
Else
While _NextLink( objLink )
If i = pIndex Then
' Save object for returning
obj = objLink._value
' Delete object
objLink._value = Null
' Connect previous and next node of deleted obj
objLink._succ._pred = objLink._pred
objLink._pred._succ = objLink._succ

_count:-1
Return obj
EndIf
i :+ 1
Wend
EndIf
Return Null
End Method

' Get object from list at given index
Method FromList:Object( pIndex:Int )
Local i:Int = 1
Local listCount:Int = Self.Count()

' Get head of list
Local objLink:TLink = Self._head

If pIndex >= listCount
Return Self.Last()
ElseIf pIndex <= 1
Return Self.First()
Else
While _NextLink( objLink )
If i = pIndex Then
Return objLink._value
EndIf
i :+ 1
Wend
EndIf
Return Null
End Method

' Replace the object at the given index with the given object
Method ToList:TLink( value:Object, pIndex:Int )
Local newLink:TLink = New TLink, i:Int = 1
Assert value Else "Can't insert Null object into list"

' Get head of list
Local objLink:TLink = Self._head

While _NextLink( objLink )
If i = pIndex Then
objLink._value = value
Return objLink
EndIf
i :+ 1
Wend
End Method

' Returns the index of the given object
Method Index:Int(value:Object)
Local i:Int = 1
' Get head of list
Local objLink:TLink = Self._head

While _NextLink( objLink )
If value = objLink._value
Return i
EndIf
i :+ 1
Wend
Return Null
End Method

End Type



TListEx kann ganz wie gewohnt wie TList benutzt werden! Folgend ein Beispiel:

Beispiel:
BlitzMax: [AUSKLAPPEN]

Local list:TListEx = New TListEx

Local index:Int = 5

list.AddLast("Element: 1")
list.AddLast("Element: 2")
list.AddLast("Element: 3")
list.AddLast("Element: 4")
list.AddLast("Element: 5")
list.AddLast("Element: 6")
list.AddLast("Element: 7")
list.AddLast("Element: 8")
list.AddLast("Element: 9")
list.AddLast("Element: 10")

Print ""

Print "List's content: " + list.Count() + " elements."
For Local obj:String = EachIn list
Print obj
Next
Print ""

obj = "Element: new"

Print "Pushing new element to list at index " + index + "..."
list.Push( obj, index )

obj = ""
Print ""

Print "List's content: " + list.Count() + " elements."
For obj:String = EachIn list
Print obj
Next

obj = ""
Print ""

Print "Popping element at index " + index + " from list..."
obj = String( list.Pop(index) ) ' Beachte: Wie zu sehen ist, muss das Objekt wieder zurück konvertiert werden um gewohnten Zugriff zu haben ( String(Object) )
Print "Popped element: "+ obj

obj = ""
Print ""

Print "List's content: " + list.Count() + " elements."
For obj:String = EachIn list
Print obj
Next

obj = ""
Print ""

Print "Get element at index " + index + " from list without deleting it..."
obj = String( list.FromList(index) ) ' Beachte: Wie zu sehen ist, muss das Objekt wieder zurück konvertiert werden um gewohnten Zugriff zu haben ( String(Object) )
Print "Received element: "+ obj


obj = ""
Print ""

Print "List's content: " + list.Count() + " elements."
For obj:String = EachIn list
Print obj
Next


obj = ""
Print ""

obj = "Element: replaced"

Print "Replacing element at index " + index + " of list..."
list.ToList( obj, index )

obj = ""
Print ""

Print "List's content: " + list.Count() + " elements."
For obj:String = EachIn list
Print obj
Next



Und der Output des Beispiels:
Code: [AUSKLAPPEN]
List's content: 10 elements.
Element: 1
Element: 2
Element: 3
Element: 4
Element: 5
Element: 6
Element: 7
Element: 8
Element: 9
Element: 10

Pushing new element to list at index 5...

List's content: 11 elements.
Element: 1
Element: 2
Element: 3
Element: 4
Element: new
Element: 5
Element: 6
Element: 7
Element: 8
Element: 9
Element: 10

Popping element at index 5 from list...
Popped element: Element: new

List's content: 10 elements.
Element: 1
Element: 2
Element: 3
Element: 4
Element: 5
Element: 6
Element: 7
Element: 8
Element: 9
Element: 10

Get element at index 5 from list without deleting it...
Received element: Element: 5

List's content: 10 elements.
Element: 1
Element: 2
Element: 3
Element: 4
Element: 5
Element: 6
Element: 7
Element: 8
Element: 9
Element: 10

Replacing element at index 5 of list...

List's content: 10 elements.
Element: 1
Element: 2
Element: 3
Element: 4
Element: replaced
Element: 6
Element: 7
Element: 8
Element: 9
Element: 10

Process complete



### EDIT ###

Habe noch die Methode "Index" hinzugefügt welche den Index eines Objekts zurückgibt (siehe Beschreibung oben).

G,
Trust

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group