Seite 1 von 1

Map wird nicht bis zum Ende befüllt.

Verfasst: 24.02.2012 17:41
von alen
Hallo Community,

ich spiele gerade ein wenig mit Maps herum, da ich Sie für eine dynamiche Ausgabe von Daten gebrauchen kann und mir fällt dabei auf, dass meine Map, die ich hier unten generiere, nicht bis zum letzten Element gefüllt wird oder die Anzeige im unteren Teil mit NextMapElement(t()) nicht komplett ist.

Andere seltsame Erscheinung:
Wenn ich den Zähler i auf 40 setze (also zähle bis 40) läuft das Programm durch und wird beendet ohne Debug Ausgaben zu erzeugen.

Hat hier jemand von Euch eine Idee ?
Meine Experimente laufen auf Windows XP 32 Bit Basis mit dem Purbasic 4.61 Beta 1.

Grüße
Alen

Hier der Quellcode und die Ausgaben:

Code: Alles auswählen

EnableExplicit

Define.l i
NewMap t.s()

For i= 1 To 39
  AddMapElement(t(), "key" + Str(i))
  t() = "value" + Str(i)
Next

While NextMapElement(t())
  Debug MapKey(t()) + " - " + t()
Wend
Meine Ausgabe:

Code: Alles auswählen

key1 - value1
key2 - value2
key3 - value3
key4 - value4
key5 - value5
key6 - value6
key7 - value7
key8 - value8
key9 - value9
Lasse ich das ganze mit einer ForEach Schleife durchlaufen bekomme ich seltsam und unsortierte Ergebnisse:

Code: Alles auswählen

ForEach t()
  Debug MapKey(t()) + " - " + t()
Next
Ausgabe:

Code: Alles auswählen

key10 - value10
key11 - value11
key12 - value12
key13 - value13
key14 - value14
key15 - value15
key16 - value16
key17 - value17
key18 - value18
key19 - value19
key20 - value20
key21 - value21
key22 - value22
key23 - value23
key24 - value24
key25 - value25
key26 - value26
key27 - value27
key28 - value28
key29 - value29
key30 - value30
key31 - value31
key32 - value32
key33 - value33
key34 - value34
key35 - value35
key36 - value36
key37 - value37
key38 - value38
key39 - value39
key1 - value1
key2 - value2
key3 - value3
key4 - value4
key5 - value5
key6 - value6
key7 - value7
key8 - value8
key9 - value9

Re: Map wird nicht bis zum Ende befüllt.

Verfasst: 24.02.2012 17:54
von Nino
Entweder du schreibst vor die letzte Schleife

Code: Alles auswählen

ResetMap(t())
oder du benutzt eine ForEach-Schleife.
Kuck dir am besten mal in Ruhe alle Map-Befehle an -- sind nicht so viele. :-)

Die Elemente einer Map können zufällig mal sortiert sein, grundsätzlich kann man das aber nicht voraussetzen. Wenn du das brauchst, musst du eine Linked List oder ein Array nehmen.

Re: Map wird nicht bis zum Ende befüllt.

Verfasst: 24.02.2012 17:58
von Kiffi
Hallo Alen,

in Deinem ersten Code fehlt ein ResetMap(t()) zwischen Befüllen und Ausgabe der Map.
alen hat geschrieben:Lasse ich das ganze mit einer ForEach Schleife durchlaufen bekomme ich seltsam und unsortierte Ergebnisse:
das ist so korrekt. Maps sind nicht sortiert.

Grüße ... Kiffi

Re: Map wird nicht bis zum Ende befüllt.

Verfasst: 24.02.2012 18:10
von alen
Hallo Nino,

unter ResetMap hätte mir nicht das setzen eines Zeigers auf den Anfang vorgestellt.
Falsche Assoziation des Begiffes. So ist es wenn man sich zum ersten Mal damit befasst.
Jetzt muss ich das ganze noch für meinen Anwendungsfall ausbauen.

Aber hast recht die Map Befehle sind sehr übersichtlich.

Danke für die Hilfe, es klappt.

Grüße
Alen

Re: Map wird nicht bis zum Ende befüllt.

Verfasst: 24.02.2012 21:00
von jear
@alen

Man kann nicht sicher sein, dass eine Map sortiert ist. Aber mit Deiner Methode, die Keys zu befüllen, kann es sowieso nichts werden.

Code: Alles auswählen

EnableExplicit

Define.l i
NewMap t.s()

For i = 1 To 39
  AddMapElement(t(), "key" + RSet(Str(i), 2, "0"))
  t() = "value" + Str(i)
Next

ForEach t()
  Debug MapKey(t()) + " - " + t()
Next

Re: Map wird nicht bis zum Ende befüllt.

Verfasst: 24.02.2012 23:05
von Kiffi
Anmerkung: man benötigt nicht unbedingt AddMapElement()

Code: Alles auswählen

EnableExplicit

Define.l i
NewMap t.s()

For i = 1 To 39
  t("key" + RSet(Str(i), 2, "0")) = "value" + Str(i)
Next

ForEach t()
  Debug MapKey(t()) + " - " + t()
Next
Grüße ... Kiffi

Re: Map wird nicht bis zum Ende befüllt.

Verfasst: 27.02.2012 12:58
von alen
Hallo Kiffi,

das liest sich doch gut. Warum ich das ganze gerade mal anteste ist, ich will gerne aus einer Datenbank Abfrage die Ergebnisdaten in eine Map packen und damit dann ein Listview Element befüllen. Also etwas komfortablere Möglichkeit dynamische Listviews zu erzeugen. Datengrid aus Map sozusagen.

Da bin ich mir nur nicht sicher ob ich auf dem richtigen Weg bin. Wenn ich eine Map mit einer Struktur versehe muss ich die Struktur schliesslich immer manuell vorgeben. Ich würde aber gerne die Struktur ggf. zur Laufzeit erzeugen. Geht das in PB überhaupt ? Suche im Moment nach einem praktikablen Vorgehen.

In diesem Sinne. Frohes Schaffen.
Grüße
Alen

Re: Map wird nicht bis zum Ende befüllt.

Verfasst: 27.02.2012 14:23
von NicTheQuick
Ich habe mal auf die Schnelle eine solche dynamische Struktur für dich gebastelt, die man zur Laufzeit erstellen und nutzen kann. Du musst sie jetzt nur noch mit einer Map verknüpfen. Ein Beispiel dazu ist am Ende zu sehen.

Code: Alles auswählen

EnableExplicit

Structure BasicTypes
	StructureUnion
		a.a
		b.b
		c.c
		d.d
		f.f
		i.i
		l.l
		q.q
		s.String
		u.u
		w.w
	EndStructureUnion
EndStructure

Structure DynamicStructure
	types.s
	*data.BasicTypes[0]
EndStructure

Macro newDynamicStructureElement(dynamicStructure, position, structureName)
	dynamicStructure\data[position] = AllocateMemory(SizeOf(structureName))
	If Not dynamicStructure\data[position]
		ProcedureReturn #False
	EndIf
	InitializeStructure(dynamicStructure\data[position], structureName)
EndMacro

Macro freeDynamicStructureElement(dynamicStructure, position, structureName)
	ClearStructure(dynamicStructure\data[position], structureName)
	FreeMemory(dynamicStructure\data[position])
EndMacro

Procedure freeDynamicStructure(*ds.DynamicStructure)
	Protected elements.i = Len(*ds\types)
	
	Protected *c.Character = @*ds\types
	Protected i.i = 0, size.i
	
	While *c\c
		Select *c\c
			Case 'a': freeDynamicStructureElement(*ds, i, Ascii)
			Case 'b': freeDynamicStructureElement(*ds, i, Byte)
			Case 'c': freeDynamicStructureElement(*ds, i, Character)
			Case 'd': freeDynamicStructureElement(*ds, i, Double)
			Case 'f': freeDynamicStructureElement(*ds, i, Float)
			Case 'i': freeDynamicStructureElement(*ds, i, Integer)
			Case 'l': freeDynamicStructureElement(*ds, i, Long)
			Case 'q': freeDynamicStructureElement(*ds, i, Quad)
			Case 's': freeDynamicStructureElement(*ds, i, String)
			Case 'u': freeDynamicStructureElement(*ds, i, Unicode)
			Case 'w': freeDynamicStructureElement(*ds, i, Word)
			Default:
				ProcedureReturn #False
		EndSelect
		
		i + 1
		*c + SizeOf(Character)
	Wend
	
	ClearStructure(*ds, DynamicStructure)
	FreeMemory(*ds)
EndProcedure

Procedure.i newDynamicStructure(types.s)
	Protected elements.i = Len(types)
	Protected *ds.DynamicStructure = AllocateMemory(SizeOf(DynamicStructure) + SizeOf(Integer) * elements) ;because SizeOf(Integer) == SizeOf(Pointer)
	InitializeStructure(*ds, DynamicStructure)
	*ds\types = ""
	
	Protected *c.Character = @types
	Protected i.i = 0, size.i
	
	While *c\c
		Select *c\c
			Case 'a': newDynamicStructureElement(*ds, i, Ascii)
			Case 'b': newDynamicStructureElement(*ds, i, Byte)
			Case 'c': newDynamicStructureElement(*ds, i, Character)
			Case 'd': newDynamicStructureElement(*ds, i, Double)
			Case 'f': newDynamicStructureElement(*ds, i, Float)
			Case 'i': newDynamicStructureElement(*ds, i, Integer)
			Case 'l': newDynamicStructureElement(*ds, i, Long)
			Case 'q': newDynamicStructureElement(*ds, i, Quad)
			Case 's': newDynamicStructureElement(*ds, i, String)
			Case 'u': newDynamicStructureElement(*ds, i, Unicode)
			Case 'w': newDynamicStructureElement(*ds, i, Word)
			Default:
				freeDynamicStructure(*ds)
				ProcedureReturn #False
		EndSelect
		
		i + 1
		*ds\types + Chr(*c\c)
		*c + SizeOf(Character)
	Wend
	
	ProcedureReturn *ds
EndProcedure

;=================== EXAMPLE ===================

Define *ds.DynamicStructure


;Definiere eine Struktur anhand der Kurzbezeichnungen von PB
*ds.DynamicStructure = newDynamicStructure("iisls")

;Jetzt können wir die einzelnen Positionen beschreiben.
*ds\data[0]\i = 123
*ds\data[1]\i = -456
;Auf Strings müssen wir auf Grund einer Sicherheitsmaßnahme in PB etwas komplizierter zugreifen.
*ds\data[2]\s\s = "Test"
*ds\data[3]\l = 789
*ds\data[4]\s\s = "String"

;Danach kann man die Werte wieder lesen
Debug *ds\data[0]\i
Debug *ds\data[1]\i
Debug *ds\data[2]\s\s
Debug *ds\data[3]\l
Debug *ds\data[4]\s\s

;Und wenn wir die dynamische Struktur nicht mehr brauchen, sollten wir sie wieder freigeben.
freeDynamicStructure(*ds)