Brauche Hilfe beim Sortieren

Anfängerfragen zum Programmieren mit PureBasic.
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Brauche Hilfe beim Sortieren

Beitrag von bin_neu_hier »

Hallo,

ich möchte folgendes tun:

Eine Reihe von Dateien sollen eingelesen werden, in denen die Daten immer wie folgt vorliegen:
Datum
Wert1
Wert2
...
Wert15

Der Datumswert liegt als "Sekundenwert" vor (den man beispielsweise mit

Code: Alles auswählen

Debug Date()
erhalten würde). Die Anzahl der Dateien ist unbekannt, die Werte liegen als Strings vor und können ebenfalls in der Länge variieren.

Ich hatte vor, die Dateien auszulesen und die Inhalte in einen String zu schreiben, jeden Einzelwert durch "|" getrennt, und die Daten jeder Datei durch "§" getrennt, um dann jeden einzelnen Satz mit

Code: Alles auswählen

StringField(gesamtstring$, "§")
und jeden Einzelwert mit

Code: Alles auswählen

StringField(einzelstring$, "|")
auszulesen.

Wie kann ich die Sätze im Gesamtstring nach dem Datumswert sortieren?

Wenn das nur mit einem Array ginge, wie DIMensioniere ich ein Array, wenn ich vorher nicht wissen kann, wieviele Daten zu verarbeiten sind? Wäre das mit (sinngemäß, kein richtiger Code)

Code: Alles auswählen

dim 1
while  (noch mehr Dateien vorhanden)
redim +1
wend
sinnvoll oder gibt es da was Sinnvolleres?
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
ST4242
Beiträge: 42
Registriert: 29.10.2011 16:54

Re: Brauche Hilfe beim Sortieren

Beitrag von ST4242 »

Hallo,

an deiner Stelle würde ich eine Structur erstellen

Structure Werte
Datum.i
wert1
wert2
...
endstructure


und von dieser eine LinkedList erstellen

NewList Liste().Werte

Damit kann jede Datei ein Listenelement eingefügt werden, als auch über dir Sortierfunktionen sortiert werden.

Daher bitte mal die Themen Strukturen als auch PureBasic - List in der Hilfe nachschlagen.

Ich hoffe das hilft weiter
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Brauche Hilfe beim Sortieren

Beitrag von Bisonte »

Geht es jetzt darum, aus vielen einzelnen Dateien immer nur einen String auszulesen und dies dann zu sortieren ?

Dann nehme eine Liste :

Code: Alles auswählen

NewList String.s()

While (nächste Datei)

  AddElement(String())
  String() = Eingelesener String

Wend

; Sortieren
SortList(String(), #PB_Sort_Ascending)
; Ausgeben
Foreach String()
  Debug String()
Next

PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Brauche Hilfe beim Sortieren

Beitrag von NicTheQuick »

Ich würde auch eine Struktur und eine Liste nutzen. Wenn pro Datei immer 15 Datenwerte vorhanden sind, dann sollte es sogar mit sowas simplem wie dem hier gehen:

Code: Alles auswählen

Structure File
	filename.s
	timestamp.i
	value.s[15]
EndStructure

NewList files.File()

Procedure addFile(List files.File(), filename.s)
	Protected fileId.i
	
	fileId = ReadFile(#PB_Any, filename)
	If Not fileId
		ProcedureReturn #False
	EndIf
	
	If Not AddElement(files())
		ProcedureReturn #False
	EndIf
	
	files()\filename = filename
	files()\timestamp = Val(ReadString(fileId))
	Protected i.i
	For i = 0 To 14
		files()\value[i] = ReadString(fileId)
	Next
	
	CloseFile(fileId)
EndProcedure

addFile(files(), "/tmp/datei1.txt")
addFile(files(), "/tmp/datei2.txt")
addFile(files(), "/tmp/datei3.txt")
addFile(files(), "/tmp/datei4.txt")
addFile(files(), "/tmp/datei5.txt")

SortStructuredList(files(), #PB_Sort_Ascending, OffsetOf(File\timestamp), #PB_Integer)

Debug "Dateinamen sortiert nach Zeitstempel"
ForEach files()
	Debug files()\filename
Next
Bild
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Brauche Hilfe beim Sortieren

Beitrag von mk-soft »

Wie sehen die Daten aus?

- Erste Zeile Spaltennamen
- Trennzeichen in Datei
- Ist es eine CSV

Solltest mit Strukturen und LinkedList mal anfangen!
Werde mal ein kleines Beispiel schreiben...

Fertig mit Dynamischen Columns

Update
Wenn es nur für Windows ist, kann man die Automation von MS verwenden um ein Datums String in beliebiger form
in ein TimeStamp von type Double zu wandeln.

Code: Alles auswählen

;-TOP

;-Strukturen

Structure udtDataColumns
  RecID.i ; Intern
  TimeStamp.d ; Intern
  Datum.s ; 
  List Column.s() ; Dynamische Columns nach Feld Datum
EndStructure

;-Functions

Procedure LoadData(FileName.s, Separator.s, List Result.udtDataColumns(), IgnoreFirstLine = #False)
  Protected file, bom, line.s, datum.s, col, count, index
  Protected vTime.Variant, vTimeStamp.Variant
  
  file = ReadFile(#PB_Any, FileName)
  If file = 0
    Debug "Fehler - Datei öffnen: " + FileName
    ProcedureReturn 0
  EndIf
  bom = ReadStringFormat(file)
  If bom <> #PB_Ascii And bom <> #PB_UTF8 And bom <> #PB_Unicode
    Debug "Fehler - BOM wird nicht unterstützt"
    CloseFile(file)
    ProcedureReturn -1
  EndIf
  If IgnoreFirstLine
    If Not Eof(file)
      line = ReadString(file, bom)
    EndIf
  EndIf
  While Not Eof(file)
    line = ReadString(file, bom)
    col = CountString(line, Separator)
    count + 1
    If AddElement(Result()) = 0
      Debug "Fehler - Out Of Memory"
      CloseFile(file)
      ProcedureReturn -2
    EndIf
    Result()\RecID = count
    datum = StringField(line, 1, Separator)
    
    ; Nutzung der Automation zur Datumsanpassung
    vTime\vt = #VT_BSTR
    vTime\bstrVal = SysAllocString_(@Datum)
    If VariantChangeType_(vTimeStamp, vTime, 0, #VT_DATE) = #S_OK
      Result()\TimeStamp = vTimeStamp\date
    EndIf
    VariantClear_(vTime)
    ; Ende
    
    Result()\Datum = Datum
    For index = 2 To col +1
      AddElement(Result()\Column())
      Result()\Column() = StringField(line, index, Separator)
    Next
  Wend
  CloseFile(file)
  ProcedureReturn ListSize(Result())
  
EndProcedure

Procedure OutputData(List Result.udtDataColumns())
  Protected output.s
  output = "RecID" + #TAB$ + "TimeStamp" + #TAB$ +"Datum" + #TAB$ + "Column, ..."
  Debug output
  ForEach Result()
    output = "" + Result()\RecID + #TAB$ + Result()\TimeStamp + #TAB$ + Result()\Datum
    ForEach Result()\Column()
      output + #TAB$ + Result()\Column()
    Next
    Debug output
  Next
EndProcedure


Procedure CreateData(FileName.s)
  Protected file, line.s
  
  file = CreateFile(#PB_Any, FileName)
  If file
    Restore DummyData
    Read.s line
    While line <> ""
      WriteStringN(file, line, #PB_UTF8)
      Read.s Line
    Wend
    CloseFile(file)
  EndIf
EndProcedure

;-Test

Global NewList Rows.udtDataColumns()

CreateData(GetHomeDirectory() + "Dummy.dat")

ClearList(Rows())
count = LoadData(GetHomeDirectory() + "Dummy.dat", ",", Rows())
Debug "Count Of Rows = " + count
SortStructuredList(Rows(), #PB_Sort_Ascending, OffsetOf(udtDataColumns\TimeStamp), #PB_Double)

OutputData(Rows())

End
DataSection
  DummyData:
  Data.s "23.05.2017 18:00,2,3,4,5"
  Data.s "2019.06.020,100,200,300,400,500,600,700"
  Data.s "2018-01-01,A,C,D"
  Data.s "15.6.2015 12:00,A1,C2,D3"
  Data.s ""
EndDataSection
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Uff!

Beitrag von bin_neu_hier »

Hallo Allerseits und besten Dank an alle für eure Beiträge.

Das will jetzt erst mal verdaut werden ...
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Antworten