Durchlauf von Map mit ForEach

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Durchlauf von Map mit ForEach

Beitrag von techniker »

Hallo zusammen,

eine kurze (und ggf. dumme) Frage:
Wenn ich eine Map mehrmals mit ForEach abarbeite, ist dann die Reihenfolge der Elemente immer gleich?

Danke! :)
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Benutzeravatar
TroaX
Beiträge: 659
Registriert: 08.03.2013 14:27
Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Pop_OS! | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Pop_OS!
Wohnort: NRW
Kontaktdaten:

Re: Durchlauf von Map mit ForEach

Beitrag von TroaX »

Moin,

generell schon. Es gibt keinen rationalen Grund, warum die Map jedes mal gewürfelt werden sollte. Eine zufällige (zumindest zufällig wirkende) Reihenfolge müsste ja durch etwas forciert werden. ForEach fängt immer beim ersten Element an und läuft, wenn nicht durch eine Abbruchbedingung unterbrochen, bis zum letzten Element durch. Und die Reihenfolge bleibt dabei unberührt. Das würde sonst dem System mehr Rechenzeit unnötig abverlangen, als es muss. Schließlich sind die ja im Speicher auch in der Reihenfolge hinterlegt, wie die Elemente angelegt wurden ;)

Code: Alles auswählen

EnableExplicit

OpenConsole()

NewMap MultipleRunner.s()
Define.i Counter

MultipleRunner("Test_1") = "Test_1"
MultipleRunner("Test_2") = "Test_2"
MultipleRunner("Test_3") = "Test_3"
MultipleRunner("Test_4") = "Test_4"
MultipleRunner("Test_5") = "Test_5"
MultipleRunner("Test_6") = "Test_6"
MultipleRunner("Test_7") = "Test_7"
MultipleRunner("Test_8") = "Test_8"
MultipleRunner("Test_9") = "Test_9"

For Counter = 1 To 10
  ForEach MultipleRunner()
    PrintN(MapKey(MultipleRunner()) + " " + MultipleRunner())
    If MultipleRunner() = "Test_6" And Mod(Counter, 2) = 0
      Break
    EndIf
  Next
  PrintN("")
Next

Input()
Output:

Code: Alles auswählen

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6
Test_7 Test_7
Test_8 Test_8
Test_9 Test_9

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6
Test_7 Test_7
Test_8 Test_8
Test_9 Test_9

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6
Test_7 Test_7
Test_8 Test_8
Test_9 Test_9

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6
Test_7 Test_7
Test_8 Test_8
Test_9 Test_9

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6
Test_7 Test_7
Test_8 Test_8
Test_9 Test_9

Test_1 Test_1
Test_2 Test_2
Test_3 Test_3
Test_4 Test_4
Test_5 Test_5
Test_6 Test_6
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Pop_OS!
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Pop_OS!
NAS: Fritz.Box :lol:
Coding: Purebasic 6.04 | PHP | HTML | CSS | Javascript
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Re: Durchlauf von Map mit ForEach

Beitrag von techniker »

Das Ergebnis hatte ich auch - aber ich weiß nicht, ob das immer so ist.
99,5% von meinem Programm nutzt die Map am effektivsten durch das FindMapElement().
Es gibt aber einen Punkt, bei dem ich die Einmaligkeit der Element-Werte prüfen muss..

Das ist dann eine verschachtelte ForEach() auf die gleiche Map.
Wenn die Reihenfolge immer gleich ist, könnte ich die untere ForEach() mit einem anderen
Offset starten und somit wird die Funktion schneller..

(Schwierig zu erklären..)
Zuletzt geändert von techniker am 20.01.2023 10:09, insgesamt 1-mal geändert.
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Durchlauf von Map mit ForEach

Beitrag von STARGÅTE »

techniker hat geschrieben: 20.01.2023 08:46 Wenn ich eine Map mehrmals mit ForEach abarbeite, ist dann die Reihenfolge der Elemente immer gleich?
Das ist keine zwingende Bedingung bei Maps. Bei einer Linked List sind die Elemente, wie es der Name schon sagt verknüpft und jedes Element kennt seinen Vorgänger und seinen Nachfolger. Map-Elemente sind nicht verknüpft.
Es wäre jedoch durchaus plausibel, wenn sich die Reihenfolge zumindest nicht ändert, solange kein Element hinzugefügt oder entfernt wird. Eine Garantie gibt es dafür aber nicht.
Außerdem muss es nicht einmal sein, dass die Reihenfolge von PB-Version zu PB-Version erhalten bleibt, wenn sich etwas am Hash-Algorithmus der Map ändert.
TroaX hat geschrieben: 20.01.2023 09:29 Schließlich sind die ja im Speicher auch in der Reihenfolge hinterlegt, wie die Elemente angelegt wurden
Nein das stimmt nicht. In deinem Beispiel sieht das so aus, weil die Keys eine gewisse Reihenfolge haben. Im allgemeinen, werden die Elemente aber nicht so durchlaufen, wie sie angelegt wurden.

Code: Alles auswählen

Define NewMap Example.s()

Example("Some String") = "1"
Example("Another String") = "2"
Example("Any String") = "3"
Example("An additional String") = "4"

ForEach Example()
	Debug "Example(" + MapKey(Example()) + ") = " + Example()
Next

Debug "---"

Example("A new String") = "5"

ForEach Example()
	Debug "Example(" + MapKey(Example()) + ") = " + Example()
Next
Edit:
techniker hat geschrieben: 20.01.2023 09:47 Es gibt aber einen Punkt, bei dem ich die Einmaligkeit der Element-Werte prüfen muss..

Das ist dann eine verschachtelte ForEach() auf die gleiche Map.
Wenn die Reihenfolge immer gleich ist, könnte ich die untere ForEach() mit einem anderen
Offset starten und somit wird die Funktion schneller..

(Schwierig zu erklären..)
Dafür gibt es ein Beispiel in der Hilfe:
https://www.purebasic.com/german/docume ... ition.html
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
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Durchlauf von Map mit ForEach

Beitrag von mk-soft »

Man verwendet ja Maps um nicht durchsuchen zu müssen und ist somit schon sehr schnell.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Lord
Beiträge: 313
Registriert: 21.01.2008 19:11

Re: Durchlauf von Map mit ForEach

Beitrag von Lord »

Hi!

Wenn ich eine Map nutze und wissen muß, ob ein Element mehrfach vorkommt,
nutze ich eine Struktur. ein Element der Struktur ist dann ein Counter, welcher
bei dem Hinzufügen eines Elements um ein erhöht wird.
Bei der Abfrage des Elements wird diese Counter dann auf einen Wert größer
als eins geprüft.
Bild
Benutzeravatar
TroaX
Beiträge: 659
Registriert: 08.03.2013 14:27
Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Pop_OS! | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Pop_OS!
Wohnort: NRW
Kontaktdaten:

Re: Durchlauf von Map mit ForEach

Beitrag von TroaX »

STARGÅTE hat geschrieben: 20.01.2023 10:08 Nein das stimmt nicht. In deinem Beispiel sieht das so aus, weil die Keys eine gewisse Reihenfolge haben. Im allgemeinen, werden die Elemente aber nicht so durchlaufen, wie sie angelegt wurden.
Hmm ich habe den PureBasic-Compiler für ziemlich primitiv gehalten. Das überrascht mich jetzt. Erklärt zwar nicht, warum das so ist. Aber wenn dem so ist, ziehe ich meine Aussage zurück. Für so etwas habe ich Maps sowieso nicht genutzt. Siehe mk-soft :lol:
Man verwendet ja Maps um nicht durchsuchen zu müssen und ist somit schon sehr schnell.
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Pop_OS!
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Pop_OS!
NAS: Fritz.Box :lol:
Coding: Purebasic 6.04 | PHP | HTML | CSS | Javascript
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Re: Durchlauf von Map mit ForEach

Beitrag von techniker »

mk-soft hat geschrieben: 20.01.2023 12:39 Man verwendet ja Maps um nicht durchsuchen zu müssen und ist somit schon sehr schnell.
Wie erkennst du sonst, welche Keys von Dubletten betroffen sind?
(Dubletten sollen nicht verboten sein, aber müssen detektiert werden)
Die Map hat momentan bis zu 70'000 Elemente.

obst("key1") = "Apfel"
obst("Key2") = "Birne"
obst("key3") = "Banane"
obst("key4") = "Birne"
obst("key5") = "Weintraube"
obst("key6") = "Banane"
obst("key7") = "Banane"

Bei diesem Beispiel brauche ich folgende Keys als Ergebnis:
key2, key3, key4, key6, key7
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Durchlauf von Map mit ForEach

Beitrag von mk-soft »

Map Keys müssen eindeutig sein. Sonst ist der schnelles zugriff nicht möglich. Man kann zwar mehrere Keys mit gleichen Namen anlegen. Es ist aber immer nur der letzte zu greifbar bis diese gelöscht wird (siehe PB-Help AddMapElemenet)

Für ähnliche fälle verwende ich ein Zusammenspiel für LinkedList für die Daten und Maps für Index verweise.

Code: Alles auswählen


Structure udtMyData
  Name.s
  Value.i
EndStructure

Global NewList MyData.udtMyData()
Global NewMap *IndexMyData.udtMyData()

; Dummy Data

For i = 1 To 100
  AddElement(MyData())
  MyData()\Name = "Name_" + i
  MyData()\Value = Random(1000)
Next

; Build Index
ForEach MyData()
  *IndexMyData(MyData()\Name) = @MyData()
Next

If FindMapElement(*IndexMyData(), "Name_1")
  Debug *IndexMyData()\Value
EndIf

If FindMapElement(*IndexMyData(), "Name_50")
  Debug *IndexMyData()\Value
EndIf
Zuletzt geändert von mk-soft am 20.01.2023 14:07, insgesamt 1-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Re: Durchlauf von Map mit ForEach

Beitrag von techniker »

mk-soft hat geschrieben: 20.01.2023 13:56 Map Keys müssen eindeutig sein. Sonst ist der schnelles zugriff nicht möglich.
Das ist mir schon klar - darum nutze ich ja auch Maps.. :mrgreen:
Wie gesagt: 99,5% von der Software nutzen Maps genau wegen dem schnellen Zugriff.

Es gibt aber EINE Funktion, welche Dubletten erkennen muss.
Und wie soll ich die enthaltenen Werte sonst prüfen, als sequentielles abarbeiten? :)
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Antworten