Mein Vorschlag: In dem man Werte mit Hilfe einer eigenen Setter-Prozedur in ein Element schreibt und dabei auf eine Dublette prüft. Dann muss die Schleife nur ein einziges mal beim schreiben eines Wertes durchlaufen, wenn du einen neuen Eintrag einsetzt. Dadurch verteilt sich die Last in den Arbeitsfluss und muss nicht auf einen Schlag erbracht werden.techniker hat geschrieben: 20.01.2023 14:02Und wie soll ich die enthaltenen Werte sonst prüfen, als sequentielles abarbeiten?
Durchlauf von Map mit ForEach
- TroaX
- Beiträge: 684
- Registriert: 08.03.2013 14:27
- Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Linux Mint | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Linux Mint
- Wohnort: NRW
- Kontaktdaten:
Re: Durchlauf von Map mit ForEach
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Linux Mint
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Linux Mint
NAS: Fritz.Box 5690 Pro (Nur für Keepass-DB)
Coding: Purebasic, Spiderbasic, GDevelop, Javascript/Node
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Linux Mint
NAS: Fritz.Box 5690 Pro (Nur für Keepass-DB)
Coding: Purebasic, Spiderbasic, GDevelop, Javascript/Node
Re: Durchlauf von Map mit ForEach
Ja, das wäre eine Überlegung wert..
Never change a running system - Never run a changed system!
(PB 6.20 LTS [x86])
(PB 6.20 LTS [x86])
Re: Durchlauf von Map mit ForEach
SQLite Datenbank im Speicher ...
Update
- Add rowID
Update
- Add rowID
Code: Alles auswählen
UseSQLiteDatabase()
Procedure CheckDatabaseUpdate(Database, Query$)
Result = DatabaseUpdate(Database, Query$)
If Result = 0
Debug DatabaseError()
EndIf
ProcedureReturn Result
EndProcedure
DatabaseFile$ = ":memory:"
If OpenDatabase(0, DatabaseFile$, "", "")
CheckDatabaseUpdate(0, "CREATE TABLE food (rowID INTEGER PRIMARY KEY AUTOINCREMENT, name CHAR(50), weight INT)")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('apple', '10')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('apple', '10')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('apple', '10')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('pear', '5')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
;If DatabaseQuery(0, "SELECT * FROM food WHERE weight > 7")
If DatabaseQuery(0, "SELECT name, count(name), sum(weight) FROM food GROUP BY name")
While NextDatabaseRow(0)
Debug GetDatabaseString(0, 1) + " Count = " + GetDatabaseLong(0, 2) + " Summe = " + GetDatabaseLong(0, 3)
Wend
FinishDatabaseQuery(0)
EndIf
CloseDatabase(0)
Else
Debug "Can't open database !"
EndIf
Zuletzt geändert von mk-soft am 20.01.2023 14:28, insgesamt 1-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Durchlauf von Map mit ForEach
! DAS IST EINE GENIALE IDEE !
Bedeutet zwar etwas Arbeit für die Umgestaltung, aber ich denke, dass sich das lohnen könnte.
Vielen dank für den Tip!
Bedeutet zwar etwas Arbeit für die Umgestaltung, aber ich denke, dass sich das lohnen könnte.
Vielen dank für den Tip!
Never change a running system - Never run a changed system!
(PB 6.20 LTS [x86])
(PB 6.20 LTS [x86])
Re: Durchlauf von Map mit ForEach
Lange Version mit Ausgabe Fenster und rowID
Code: Alles auswählen
;-TOP
; Comment : ShowDatabaseItems
; Author : mk-soft
; Version : v1.03.1
; Create : 12.02.2017
; Update : 19.08.2022
EnableExplicit
; ***************************************************************************************
Procedure GetTextWidth(Text.s, FontID.i = 0)
Static image
Protected result
If Not image
image = CreateImage(#PB_Any, 1, 1)
EndIf
If image And StartDrawing(ImageOutput(image))
If FontID
DrawingFont(FontID)
EndIf
result = TextWidth(Text)
StopDrawing()
EndIf
ProcedureReturn result
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure ClearGadgetColumns(Gadget)
CompilerIf #PB_Compiler_Version <= 551
ClearGadgetItems(Gadget)
While GetGadgetItemText(Gadget, -1, 0)
RemoveGadgetColumn(Gadget, 0)
Wend
CompilerElse
RemoveGadgetColumn(Gadget, #PB_All)
CompilerEndIf
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure CountGadgetColumns(Gadget)
Protected result
CompilerIf #PB_Compiler_Version <= 551
While GetGadgetItemText(Gadget, -1, result)
result + 1
Wend
CompilerElse
result = GetGadgetAttribute(Gadget, #PB_ListIcon_ColumnCount)
CompilerEndIf
ProcedureReturn result
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure FitColumnWidth(Gadget, Column = #PB_All)
Protected columns, rows, col, row, width, max, dx
Static help_gadget
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
If Column = #PB_All
columns = CountGadgetColumns(Gadget) - 1
For col = 0 To columns
SendMessage_(GadgetID(Gadget), #LVM_SETCOLUMNWIDTH, col, #LVSCW_AUTOSIZE_USEHEADER)
Next
Else
SendMessage_(GadgetID(Gadget), #LVM_SETCOLUMNWIDTH, Column, #LVSCW_AUTOSIZE_USEHEADER)
EndIf
CompilerElse
rows = CountGadgetItems(Gadget) - 1
dx = GetTextWidth("X", GetGadgetFont(Gadget))
If Column = #PB_All
columns = CountGadgetColumns(Gadget) - 1
For col = 0 To columns
For row = -1 To rows
width = Len(GetGadgetItemText(Gadget, row, col))
If width > max
max = width
EndIf
Next
width = max * dx + 4
SetGadgetItemAttribute(Gadget, 0, #PB_ListIcon_ColumnWidth, width, col)
width = 0
max = 0
Next
Else
For row = -1 To rows
width = Len(GetGadgetItemText(Gadget, row, Column))
If width > max
max = width
EndIf
Next
width = max * dx + 4
SetGadgetItemAttribute(Gadget, 0, #PB_ListIcon_ColumnWidth, width, Column)
EndIf
CompilerEndIf
EndProcedure
Procedure ShowDatabaseRows(Gadget, DBase, NbDecimals = 0, Hide = #False)
Protected result.i, columns.i, index.i, size.i, text.s, fltVal.f, dblVal.d
Repeat
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
Break
EndIf
If Not IsDatabase(DBase)
Break
EndIf
HideGadget(Gadget, Hide)
ClearGadgetItems(Gadget)
ClearGadgetColumns(Gadget)
columns = DatabaseColumns(DBase) - 1
Dim ColumnType(columns)
For index = 0 To columns
ColumnType(index) = DatabaseColumnType(DBase, index)
text = DatabaseColumnName(DBase, index)
size = GetTextWidth(text) + 12
AddGadgetColumn(Gadget, index, text, size)
Next
While NextDatabaseRow(DBase)
text = ""
For index = 0 To columns
Select ColumnType(index)
Case #PB_Database_Float
fltVal = GetDatabaseFloat(DBase, index)
text + FormatNumber(fltVal, NbDecimals) + #LF$
Case #PB_Database_Double
dblVal = GetDatabaseDouble(DBase, index) ; <- Bug Linux
;dblVal = ValD(GetDatabaseString(DBase, index))
text + FormatNumber(dblVal, NbDecimals) + #LF$
Default
text + GetDatabaseString(DBase, index) + #LF$
EndSelect
Next
AddGadgetItem(Gadget, -1, text)
Wend
FinishDatabaseQuery(DBase)
HideGadget(Gadget, #False)
result = CountGadgetItems(Gadget)
Until #True
ProcedureReturn result
EndProcedure
; ***************************************************************************************
CompilerIf #PB_Compiler_IsMainFile
; Constant
Enumeration ;Window
#Main
EndEnumeration
Enumeration ; Menu
#Menu
EndEnumeration
Enumeration ; MenuItems
#MenuExitApplication
EndEnumeration
Enumeration ; Gadgets
#List
#Edit
EndEnumeration
Enumeration ; Statusbar
#Status
EndEnumeration
; Global Variable
Global ExitApplication
; Functions
UseSQLiteDatabase()
Procedure CheckDatabaseUpdate(Database, Query$)
Protected Result = DatabaseUpdate(Database, Query$)
If Result = 0
Debug DatabaseError()
EndIf
ProcedureReturn Result
EndProcedure
Procedure CreateDummyDatabase(DBase)
If OpenDatabase(DBase, ":memory:", "", "")
CheckDatabaseUpdate(0, "CREATE TABLE food (rowID INTEGER PRIMARY KEY AUTOINCREMENT, name CHAR(50), weight INT)")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('apple', '10')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('apple', '10')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('apple', '10')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('pear', '5')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
CheckDatabaseUpdate(0, "INSERT INTO food (name, weight) VALUES ('banana', '20')")
Else
Debug "Can't open database !"
EndIf
EndProcedure
Procedure UpdateWindow()
Protected x, y, dx, dy, menu, status
menu = MenuHeight()
If IsStatusBar(#Status)
status = StatusBarHeight(#Status)
Else
status = 0
EndIf
x = 0
y = 0
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - menu - status
ResizeGadget(#List, x, y, dx, dy)
EndProcedure
; Main
Procedure Main()
Protected event, style, dx, dy, count
style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
dx = 800
dy = 600
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, dx, dy, "Main", style)
; Menu
CreateMenu(#Menu, WindowID(#Main))
MenuTitle("Ablage")
MenuItem(#MenuExitApplication, "Be&enden")
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
; Mac default menu
If Not IsMenu(#Menu)
CreateMenu(#Menu, WindowID(#Main))
EndIf
MenuItem(#PB_Menu_About, "")
MenuItem(#PB_Menu_Preferences, "")
CompilerEndIf
; Gadgets
#ListIconFlags = #PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines
ListIconGadget(#List, 0, 0, dx, dy, "recid", 100, #ListIconFlags)
; Statusbar
CreateStatusBar(#Status, WindowID(#Main))
AddStatusBarField(#PB_Ignore)
UpdateWindow()
;-Test database
CreateDummyDatabase(0)
If DatabaseQuery(0, "SELECT name, count(name), sum(weight) FROM food GROUP BY name")
;If DatabaseQuery(0, "SELECT * FROM sqlite_master")
count = ShowDatabaseRows(#List, 0, 3)
StatusBarText(#Status, 0, "Items: " + count)
EndIf
FitColumnWidth(#List)
; Main Loop
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
ExitApplication = #True
CompilerEndIf
Case #MenuExitApplication
ExitApplication = #True
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #List
EndSelect
Case #PB_Event_SizeWindow
Select EventWindow()
Case #Main
UpdateWindow()
EndSelect
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
ExitApplication = #True
EndSelect
EndSelect
Until ExitApplication
EndIf
EndProcedure : Main()
End
CompilerEndIf
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Durchlauf von Map mit ForEach
Momomoment...ich kann eine Datenbank einfach im RAM erstellen, indem ich als Dateinamen ":memory:" angebe? Ist das irgendwo niedergeschrieben? Woher weiß man solche Dinge und gibt es noch mehr, dass ich wissen sollte???
Guten Morgen, das ist ein schöner Tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3 TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3 TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: Durchlauf von Map mit ForEach
Das gleiche habe ich mich auch gefragt, als ich nichts davon in der Hilfe finden konnte..jacdelad hat geschrieben: 20.01.2023 14:34 Momomoment...ich kann eine Datenbank einfach im RAM erstellen, indem ich als Dateinamen ":memory:" angebe? Ist das irgendwo niedergeschrieben? Woher weiß man solche Dinge und gibt es noch mehr, dass ich wissen sollte???
Never change a running system - Never run a changed system!
(PB 6.20 LTS [x86])
(PB 6.20 LTS [x86])
- TroaX
- Beiträge: 684
- Registriert: 08.03.2013 14:27
- Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Linux Mint | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Linux Mint
- Wohnort: NRW
- Kontaktdaten:
Re: Durchlauf von Map mit ForEach
An SQLite database is normally stored in a single ordinary disk file. However, in certain circumstances, the database might be stored in memory.
Quelle: https://www.sqlite.org/inmemorydb.htmlThe special filename ":memory:" can be used anywhere that a database filename is permitted.
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Linux Mint
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Linux Mint
NAS: Fritz.Box 5690 Pro (Nur für Keepass-DB)
Coding: Purebasic, Spiderbasic, GDevelop, Javascript/Node
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Linux Mint
NAS: Fritz.Box 5690 Pro (Nur für Keepass-DB)
Coding: Purebasic, Spiderbasic, GDevelop, Javascript/Node
Re: Durchlauf von Map mit ForEach
Jahrelange Erfahrung und viel im deutschen und englischen Forum Lesen.
Die PB Hilfe kann nicht alles Enthalten. Vieles muss man dann in den Webhilfen von den verwendeten Libraries nachlesen.
Zum Bespiel wie man eigene Funktionen zum SQLite hinzufügt: SQLite create function
Die PB Hilfe kann nicht alles Enthalten. Vieles muss man dann in den Webhilfen von den verwendeten Libraries nachlesen.
Zum Bespiel wie man eigene Funktionen zum SQLite hinzufügt: SQLite create function
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Durchlauf von Map mit ForEach
Mit FindMapElement kannst Du prüfen ob das Element schon existiert.
Wenn ein Map Element schnell eingefügt wird, ohne Prüfung (No Element Check), dann wird es _vor_ dem gleichnamigen Element eingefügt (insert). Man kann mit NextMapElement() und MapKey() dann die Mehrfacheinträge abarbeiten bis die Map zu Ende ist oder ein anderer Key erscheint; FindMapElement() ändert ja auch das aktuelle Element.
Die Reihenfolge der Map entspricht der Sortierung nach dem internen Hashwert, und ist nicht alphabetisch. Daher kann ein neues Element an verschiedensten Stellen erscheinen; aber diese Stelle ist quasi mathematisch vorbestimmt, weil der Hashwert aus dem Key berechnet wird - wie eine Prüfsumme. Es wird erst nach dem Hashwert gesucht, dann wird der Key verglichen und sollte es nicht der richtige Key sein wegen einer Hashwert Kollision wird das nächste Element (rechtes Kind-Element vermutlich) mit identischem Hashwert verglichen bis der Key gefunden wurde oder ein anderer Hashwert erscheint oder die Map zu Ende ist (nix gefunden, denn).
Wenn ich mit Maps arbeite dann mache ich meistens ein FindMapElement und wenn nichts da ist ein schnelles einfügen per mit no element check. FindMapElement gibt auch den Struktur-Zeiger zurrück.
Wenn ein Map Element schnell eingefügt wird, ohne Prüfung (No Element Check), dann wird es _vor_ dem gleichnamigen Element eingefügt (insert). Man kann mit NextMapElement() und MapKey() dann die Mehrfacheinträge abarbeiten bis die Map zu Ende ist oder ein anderer Key erscheint; FindMapElement() ändert ja auch das aktuelle Element.
Die Reihenfolge der Map entspricht der Sortierung nach dem internen Hashwert, und ist nicht alphabetisch. Daher kann ein neues Element an verschiedensten Stellen erscheinen; aber diese Stelle ist quasi mathematisch vorbestimmt, weil der Hashwert aus dem Key berechnet wird - wie eine Prüfsumme. Es wird erst nach dem Hashwert gesucht, dann wird der Key verglichen und sollte es nicht der richtige Key sein wegen einer Hashwert Kollision wird das nächste Element (rechtes Kind-Element vermutlich) mit identischem Hashwert verglichen bis der Key gefunden wurde oder ein anderer Hashwert erscheint oder die Map zu Ende ist (nix gefunden, denn).
Wenn ich mit Maps arbeite dann mache ich meistens ein FindMapElement und wenn nichts da ist ein schnelles einfügen per mit no element check. FindMapElement gibt auch den Struktur-Zeiger zurrück.
Code: Alles auswählen
Procedure CheckUpdateMap(key$,value$, Map MyMap.s())
If Not FindMapElement(MyMap(), Key$)
Protected result = AddMapElement(MyMap(), Key$, #PB_Map_NoElementCheck)
MyMap() = value$
ProcedureReturn result
EndIf
ProcedureReturn #False
EndProcedure
NewMap fruits.s()
Debug CheckUpdateMap("banana","10",fruits())
Debug CheckUpdateMap("banana","10",fruits())
Debug CheckUpdateMap("banana","10",fruits())
Debug CheckUpdateMap("banana","10",fruits())
Debug CheckUpdateMap("banana","10",fruits())
Debug CheckUpdateMap("apple","10",fruits())
Debug CheckUpdateMap("apple","10",fruits())
Debug CheckUpdateMap("raspberry","10",fruits())