kleine Erweiterung für Maps

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

kleine Erweiterung für Maps

Beitrag von STARGÅTE »

Tachchen,

immer wieder stolper ich darüber, dass wenn ich mit Pointern zu MapElementen arbeiten, später nicht mehr weiß wie ich an den Key zu diesem Pointer komme...

Nach ein bisschen probieren, bin ich auf folgendes Macro gekommen:

Code: Alles auswählen

Macro MapElementKey(Pointer)
  PeekS(PeekI(Pointer-SizeOf(Integer)))
EndMacro
Zusätzlichen kann man dann auch eine "Art" ChangeCurrentMapElement() machen:

Code: Alles auswählen

Macro MapElementKey(Pointer)
  PeekS(PeekI(Pointer-SizeOf(Integer)))
EndMacro

Macro ChangeCurrentMapElement(Map, Pointer)
  FindMapElement(Map, MapElementKey(Pointer))
EndMacro

;-----

NewMap Test.i()

Test("Alpha") = 1
Test("Beta")  = 2
Test("Gamma") = 3

*Pointer = @Test("Beta")

Debug MapElementKey(*Pointer)
Debug ""

ForEach Test()
  Debug MapKey(Test())
  *Save = @Test()
  ForEach Test()
    Debug " "+MapKey(Test())
  Next
  ChangeCurrentMapElement(Test(), *Save)
Next
Ich hoffe das die Adresse zum Key auch an dieser Stelle bleibt ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: kleine Erweiterung für Maps

Beitrag von CSHW89 »

Hey danke,
genau wegen diesem Fehlen, hab ich z.Z. immer die Maps gemieden. Die doppelte ForEach-Schleife, wie in deinem Beispiel, konnte man nämlich vorher nicht machen.
Also danke, dass du mir die Tür zu den Maps geöffnet hast :bounce:

lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: kleine Erweiterung für Maps

Beitrag von STARGÅTE »

Doppelte ForEach-Schleife ging schon, nur muss mal halt statt einem Pointer (wie bei LL) den Key-Namen Speichern und dann über FindMapElement wieder "in die Schleife" springen.
Das mache ich ja immer noch, nur halt versteckt über das Macro mittels Pointer, der erst den Namen ermittelt.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: kleine Erweiterung für Maps

Beitrag von CSHW89 »

Ja ging schon, nur war das nicht sooo schnell, da durch FindMapElement erst das Element gesucht werden musste (Zeit: O(log n), mit deiner Methode: O(1), falls du die Notation kennst :mrgreen: ).
Außerdem musste man dadurch erstmal den Key haben, was bei meinen Programmen manchmal nicht ging bzw. viel komplizierter war.
lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: kleine Erweiterung für Maps

Beitrag von NicTheQuick »

Stargate wollte dir damit sagen, dass es bei seiner obigen Methode immer noch O(log(n)) ist, weil 'FindMapElement()' immer noch verwendet wird.
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: kleine Erweiterung für Maps

Beitrag von CSHW89 »

Oh stimmt, sorry :oops: . Habs falsch gelesen. Ich dachte Stargate hätte ChangeCurrentMapElement auch "zu Fuß" geschrieben. Also den Pointer des aktuellen Elements geändert.
lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: kleine Erweiterung für Maps

Beitrag von STARGÅTE »

Oke, ich probier mal, ob ich über den Pointer zum Header der Map (ist glaube ich an Position -12)
Das Aktuelle Element überschreiben kann ...

melde mich dann wieder
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: kleine Erweiterung für Maps

Beitrag von STARGÅTE »

Tia, also ich kann leider nichts weiter finden:

Code: Alles auswählen

Macro MapHeader(Pointer)
  PeekI(Pointer-SizeOf(Integer)*3)
EndMacro

NewMap Test.i()

Test("Alpha") = 11
Test("Beta")  = 22
Test("Gamma") = 33

*CurrentElement = @Test("Beta")
*MapHeader = MapHeader(*CurrentElement)

Debug *CurrentElement

Debug "MapSize : "+Str(PeekI(*MapHeader+16))

For Pos = -80 To 80 Step 4
  *Pointer = *MapHeader+Pos
  Debug RSet(Str(Pos),4)+":  "+RSet(Hex(PeekL(*Pointer),#PB_Long),8,"0")+"   "+RSet(Str(PeekL(*Pointer)),11)+"   "+PeekS(*Pointer)
Next
Was ich erkenne ist, das bei HeaderPosition+16 die Map-Größe gespeichert wird.
Darüber hinaus, kommen ab +24 alle Elemente der Map mit Header und Inhalt ...
Auch vor dem HeaderPosition steht nichts zum aktuellen Element, dort finde ich bei -44 nur die Größe eines MapElement (Header+Structure), denn wenn ich eine Map aus Quads erstelle, wird aus der 16 n 20.

Aber leider kann ich halt nirgends den Pointer des aktuellen Element wieder finden, nicht mal 12Byte kleiner, weil zB nicht der Pointer zum Inhalt gespeichert wird, sondern zum Header des Elements
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: kleine Erweiterung für Maps

Beitrag von CSHW89 »

Ich habs! Ich kenn das nämlich noch von den Listen. Da musste ich mir auch ansehen, wie sie gespeichert werden (für PBScript).
Es gibt zwei Speicherstellen, warum auch immer. Einmal den Header, den du raussuchst, und noch ein weiterer, der z.b. übergeben wird, wenn im Parameter 'Map' steht. Hier mal ein dirty-workaround, um den Wert zu bekommen (der erste Wert):

Code: Alles auswählen

Macro MapHeader(Pointer)
  PeekI(Pointer-SizeOf(Integer)*3)
EndMacro


Procedure HeaderValue(header.i)
  ProcedureReturn header
EndProcedure

Prototype HeaderValueMap(Map test.i())
HeaderValueMap.HeaderValueMap = @HeaderValue()


NewMap test.i()
test("Hallo") = 1
test("Test") = 2

Debug HeaderValueMap(test())
Debug MapHeader(@test())
An dieser Speicherposition ist direkt das aktuelle Element gespeichert. Frag mich aber nicht, wie man ihn sonst herbekommt, also für alle Arten von Maps. Da hab ich grad keine Ahnung. Werd nochmal drüber grübeln.

lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: kleine Erweiterung für Maps

Beitrag von STARGÅTE »

Seit Beta 4.60 wurde zumindest das "merken" von elementen einfacher:
Danke PushMapPosition() und PopMapPosition() kann man nun leichter zum "alten" Element springen, und da sogar in mehreren Leveln:

Code: Alles auswählen

NewMap Test.i()

Test("Alpha") = 1
Test("Beta")  = 2
Test("Gamma") = 3

ForEach Test()
  Debug MapKey(Test())
  PushMapPosition(Test())
  ForEach Test()
    Debug "  "+MapKey(Test())
    PushMapPosition(Test())
    ForEach Test()
      Debug "    "+MapKey(Test())
    Next
    PopMapPosition(Test())
  Next
  PopMapPosition(Test())
Next
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten