Listen mit "List-Wrappern"

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

Bamboo

Betreff: Listen mit "List-Wrappern"

BeitragFr, Aug 29, 2014 11:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Da ich in BlitzBasic bisher keine Möglichkeit gefunden habe, dynamische Listen mit Type-Elementen zu erzeugen, habe ich mal versucht, diese zu simulieren. Ich weiß nicht, ob es bessere Wege gibt, aber im Forum habe ich keine gesehen. Das ganze ist nicht direkt eine Bibliothek mit verschiedenen Funktionen, sondern eher eine Konzeptdarstellung. Bei meinem derzeitigen Projekt hat mir diese Lösung sehr geholfen; ich wollte für verschiedene Layer einer Grafik eine Liste mit Farben erzeugen, und diese separat voneinander anlegen.

Grundsätzlich werden Types ja bereits in Listen gespeichert. Das Problem ist, dass man für zwei verschiedene Listen auch zwei verschiedene Types deklarieren müsste. Das ist aber nicht immer gewollt, insbesondere, wenn Types andere Types als Liste enthalten sollen. Ich habe versucht, das Ganze mit Types zu lösen, die als "List-Wrapper" fungieren, also andere Type-Elemente "verpacken" und so separate, dynamische Listen mögich machen.

Also, beispielsweise möchte man mehrere Listen mit Personen machen. Eine Person wird dabei durch den Type T_Person repräsentiert:

BlitzBasic: [AUSKLAPPEN]
Type T_Person
Field name$ ;Name der Person
Field age% ;Alter der Person
End Type


Man kann mit Hilfe von "List-Wrappern" zwei Listen anlegen, die Personen enthalten. Zuerst benötigt man dazu den Wrapper-Type von T_Person, der hier T_ListablePerson heißt.

BlitzBasic: [AUSKLAPPEN]
Type T_ListablePerson
Field person.T_Person ;Verweis auf eigentliche Person
Field list% ;Nummer der Liste, zu der der List-Wrapper gehört
End Type


Der Wrapper-Type enthält lediglich zwei Felder: den Verweis auf den eigentlichen Type, und die Nummer der zugehörigen Liste. Natürlich kann man auch das Feld "list" einfach dem Type T_Person hinzufügen, aber ich wollte eine Möglichkeit schaffen, den eigentlichen Typ unberührt zu lassen. Möchte man jetzt verschiedene Listen anlegen, erstellt man für die Liste am besten einen eigenen Type:

BlitzBasic: [AUSKLAPPEN]
Type T_PersonList
Field persons.T_ListablePerson ;Verweis auf erste Person der Liste
Field id% ;Nummer der List
End Type


Dieser List-Type enthält einen Verweis auf die erste in der Liste gespeicherte Person, und eine Listennummer. Diese muss einzigartig sein; haben zwei Listen dieselbe Nummer, so können die Listen vermischt werden. Daher sollte die 0 als ID vermieden werden, da das list-Feld von T_Person immer mit 0 initalisiert wird.
Mittels einer Funktion, die hier addPersonToList heißt, kann man eine Person zu einer solchen Liste hinzufügen.

BlitzBasic: [AUSKLAPPEN]
Function addPersonToList(parList.T_PersonList, parPerson.T_ListablePerson)
;Wird nur ausgeführt, wenn die übergebene Liste und die Person initialisiert sind
If ((parPerson <> Null) And (parList <> Null)) Then
;Auch die im Wrapper-Type enthaltene Person muss initialisiert sein
If (parPerson\person <> Null)
;Dem Type-Wrapper wird die ID der Liste übergeben
parPerson\list = parList\id

;Falls die Liste leer ist, wird der Verweis auf die neue Person in parList\persons gespeichert
If (parList\persons = Null) Then
parList\persons = parPerson
;Ansonsten wird die Person dahinter eingefügt
Else
Insert parPerson After parList\persons
EndIf
EndIf
EndIf
End Function


Eine weitere Funktion namens printPersonsInList durchläuft alle Elemente der übergebenen Liste und gibt den Inhalt per Print aus:

BlitzBasic: [AUSKLAPPEN]
Function printPersonsInList(parList.T_PersonList)
;Die übergebene Liste muss initialisiert sein
If (parList <> Null) Then
Local tmpPerson.T_ListablePerson
Local shallExit% = False

Print "Personenliste " + parList\id + ": "

;Falls Personen in der Liste sind, werden die Details ausgegeben
If (parList\persons <> Null) Then
tmpPerson = parList\persons

Repeat
Print " " + tmpPerson\person\name + ", " + tmpPerson\person\age

;Der nächste Listeneintrag wird tmpPerson übergeben
tmpPerson = After tmpPerson

;Falls der neue Listeneintrag nicht vorhanden ist oder eine andere ID besitzt
;(-> das Ende der Liste erreicht ist), dann endet die Schleife
If (tmpPerson = Null) Then
shallExit = True
ElseIf (tmpPerson\list <> parList\id)
shallExit = True
EndIf
Until (shallExit)
Else
Print " Leer."
EndIf

Print ""
EndIf
End Function


Nun folgt noch zwei weitere Funktionen, um das Erstellen von Personen und Personenlisten zu vereinfachen:

BlitzBasic: [AUSKLAPPEN]
Function newListablePerson.T_ListablePerson(parName$, parAge%)
tmpPerson.T_ListablePerson = New T_ListablePerson

tmpPerson\person = New T_Person

tmpPerson\person\name = parName
tmpPerson\person\age = parAge

Return tmpPerson
End Function

Function newPersonList.T_PersonList(parID%)
tmpList.T_PersonList = New T_PersonList

tmpList\id = parID

Return tmpList
End Function


Eine weitere Funktion löscht eine Liste mitsamt ihrer eingetragenen Personen:

BlitzBasic: [AUSKLAPPEN]
Function deletePersonList(parList.T_PersonList)
If (parList <> Null) Then
Local tmpPerson.T_ListablePerson
Local shallExit% = False

If (parList\persons <> Null) Then
tmpPerson = parList\persons

Repeat
;Das Element, auf den tmpPerson verweist, wird gelöscht
Delete tmpPerson

;Der Verweis auf den nächsten Listeneintrag wird übergeben
tmpPerson = After tmpPerson

If (tmpPerson = Null) Then
shallExit = True
ElseIf (tmpPerson\list <> parList\id)
shallExit = True
EndIf
Until (shallExit)
EndIf

Delete parList
EndIf
End Function


Hat man diese Types und Funktionen definiert, sollte folgende Handhabung möglich sein:

BlitzBasic: [AUSKLAPPEN]
Type T_Person
Field name$ ;Name der Person
Field age% ;Alter der Person
End Type

Type T_ListablePerson
Field person.T_Person ;Verweis auf eigentliche Person
Field list% ;Nummer der Liste, zu der der List-Wrapper gehört
End Type

Type T_PersonList
Field persons.T_ListablePerson ;Verweis auf erste Person der Liste
Field id% ;Nummer der List
End Type





Function newListablePerson.T_ListablePerson(parName$, parAge%)
tmpPerson.T_ListablePerson = New T_ListablePerson

tmpPerson\person = New T_Person

tmpPerson\person\name = parName
tmpPerson\person\age = parAge

Return tmpPerson
End Function



Function newPersonList.T_PersonList(parID%)
tmpList.T_PersonList = New T_PersonList

tmpList\id = parID

Return tmpList
End Function



Function addPersonToList(parList.T_PersonList, parPerson.T_ListablePerson)
If ((parPerson <> Null) And (parList <> Null)) Then
If (parPerson\person <> Null)
parPerson\list = parList\id

If (parList\persons = Null) Then
parList\persons = parPerson
Else
Insert parPerson After parList\persons
EndIf
EndIf
EndIf
End Function



Function printPersonsInList(parList.T_PersonList)
If (parList <> Null) Then
Local tmpPerson.T_ListablePerson
Local shallExit% = False

Print "Personenliste " + parList\id + ": "

If (parList\persons <> Null) Then
tmpPerson = parList\persons

Repeat
Print " " + tmpPerson\person\name + ", " + tmpPerson\person\age

tmpPerson = After tmpPerson

If (tmpPerson = Null) Then
shallExit = True
ElseIf (tmpPerson\list <> parList\id)
shallExit = True
EndIf
Until (shallExit)
Else
Print " Leer."
EndIf

Print ""
Else
Print "Liste existiert nicht!"
EndIf
End Function



Function deletePersonList(parList.T_PersonList)
If (parList <> Null) Then
Local tmpPerson.T_ListablePerson
Local shallExit% = False

If (parList\persons <> Null) Then
tmpPerson = parList\persons

Repeat
Delete tmpPerson

tmpPerson = After tmpPerson

If (tmpPerson = Null) Then
shallExit = True
ElseIf (tmpPerson\list <> parList\id)
shallExit = True
EndIf
Until (shallExit)
EndIf

Delete parList
EndIf
End Function




Local list1.T_PersonList = newPersonList(1)
Local list2.T_PersonList = newPersonList(2)
Local list3.T_PersonList = newPersonList(3)

Local peter.T_ListablePerson = newListablePerson("Peter", 34)
Local lucas.T_ListablePerson = newListablePerson("Lucas", 17)
Local sarah.T_ListablePerson = newListablePerson("Sarah", 29)
Local lizzy.T_ListablePerson = newListablePerson("Lizzy", 23)

Local jason.T_ListablePerson = newListablePerson("Jason, mal wieder nicht eingeladen", 98)

addPersonToList(list1, peter)
addPersonToList(list1, sarah)
addPersonToList(list2, lizzy)
addPersonToList(list2, lucas)

printPersonsInList(list1)
printPersonsInList(list2)

deletePersonList(list1)

printPersonsInList(list1)

Local p.T_ListablePerson

;Alle jemals erzeugten Personen werden ausgegeben
For p = Each T_ListablePerson
Print p\person\name + ", " + p\person\age + "; Liste : " + p\list
Next

Input("Press any key to continue...")
End

Eingeproggt

BeitragFr, Aug 29, 2014 22:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe das von dir in der Einleitung erläuterte Problem immer so ungefähr gelöst:

Code: [AUSKLAPPEN]
Type T_Person
   Field name$      ;Name der Person
   Field age%      ;Alter der Person
   Field nextPerson.T_Person
End Type


Damit muss man sich zwar ähnlich wie du das getan hast, um das Durch-Iterieren selber kümmern. Und diesen Schritt zu abstrahieren is bestimmt nicht blöd - aber dennoch ist es irgendwie einfacher find ich. Im Grunde ist es eh dasselbe was du getan hast, nur dass ich ohne 2 weiteren Types auskomme und mich um die Verwaltung selber kümmern muss.

mfG, Christoph
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

DAK

BeitragSa, Aug 30, 2014 5:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Falls Interesse besteht kann ich eine DLL machen, die Listen und Maps in C++ nach Blitz durchschleift.

Die Listen gehen da ganz simpel. Bei den Maps würde ich String, Float, Int und Pointer auf ein Blitz-Objekt als Keys zulassen können.

Dann braucht man sich die ganze Arbeit nicht antun, und man kann Listen und Maps ganz simpel verwenden.

Braucht das wer?
Gewinner der 6. und der 68. BlitzCodeCompo

BladeRunner

Moderator

BeitragSa, Aug 30, 2014 11:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Wäre cool, DAK.
Auch wenn es wenige User sind, aber einige freuen sich sicher drüber.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group