_FileReadToArray / _ArraySort() auch mit zahlen?

  • Hallo com

    Ich habe gerade angefangen mich mit arrays ein wenig zu beschäftigen.

    Nun habe ich folgende frage,
    Kann man es so machen das ein Array sich nach zahlen sortiert?

    D.h. ich habe diese datei (songs.txt):

    Code
    1|In My Head
    5|Freedom
    11|Dynamite
    3|bla bla
    2|...
    8|.-..-.
    4|afaffa
    6|dgsr

    und den code:

    [autoit]


    Dim $aRecords
    If Not _FileReadToArray(@ScriptDir &"\data\songs.txt",$aRecords) Then
    MsgBox(4096,"Fehler", "Fehler beim einlesen der Daten.")
    Exit
    EndIf
    For $x = 1 to $aRecords[0]
    _ArraySort($aRecords) ; <---------- Hier muss das nach zahlen sortieren hin <---
    GUICtrlCreateListViewItem($aRecords[$x], $top25)
    Next

    [/autoit]

    Er soll die datei durchsuchen und von 1 bis 5 gehen
    also das er in der ersten reihe anfängt und die zahl ... for dem | sucht. wenn sie gefunden wurde dann den nächsten durchlauf von vorne das 5 mal das man sozusagen eine top5 liste hat
    also erst 1 suchen dann 2 ... usw.

    hat jemand ne idee?

    bin verzweifelt ?(

  • FileReadToArray() liest die Datei zeilenweise in ein 1D-Array.
    Um nach einer bestimmten Spalte zu sortieren benötigst du aber ein 2D-Array.
    Für deinen gezeigten Fall mal ein Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <Constants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $iMaxSpalten = 1, $iLines = 0, $Delimiter = '|' ; $Delimiter ist das Trennzeichen

    [/autoit] [autoit][/autoit] [autoit]

    ; Öffne Datei:
    $hFile = FileOpen("songs.txt", 0)
    If $hFile = -1 Then
    MsgBox(0, "Fehler", "Konnte Datei nicht öffnen.")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;Bestimme Anzahl Zeilen und Spalten des zukünftigen Arrays
    Do
    $line = FileReadLine($hFile)
    If @error = -1 Then ExitLoop
    $iLines += 1 ;erhöhe bei jeder Zeile den Zeilenzähler

    [/autoit] [autoit][/autoit] [autoit]

    ;bestimme Maximale Anzahl der Spalten
    StringReplace($line, $Delimiter, $Delimiter)
    If $iMaxSpalten < @extended + 1 Then $iMaxSpalten = @extended + 1
    Until 0

    [/autoit] [autoit][/autoit] [autoit]

    ;Erstelle Array mit der ermittelten Zeilen und Spaltenzahl
    Global $aRetArr[$iLines][$iMaxSpalten]

    [/autoit] [autoit][/autoit] [autoit]

    ;Setze Pointer wieder auf Dateianfang:
    FileSetPos($hFile, 0, $FILE_BEGIN)

    [/autoit] [autoit][/autoit] [autoit]

    ;Fülle das Array Zeile für Spalte:
    For $i = 0 To $iLines - 1
    $line = FileReadLine($hFile)
    If @error = -1 Then ExitLoop

    [/autoit] [autoit][/autoit] [autoit]

    $aSplit = StringSplit($line, $Delimiter, 2)
    If @error Then ContinueLoop
    For $x = 0 To UBound($aSplit) - 1
    ; Wenn Spalteninhalt nur Zahl und keine anderen Zeichen dann explizit als Zahl wandeln damit eine numerische Sortierung erfolgt:
    If StringRegExp($aSplit[$x], "^\d+$") Then $aSplit[$x] = Int($aSplit[$x])
    $aRetArr[$i][$x] = $aSplit[$x]
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;Schließe Dateizugriff:
    FileClose($hFile)

    [/autoit] [autoit][/autoit] [autoit]

    ;Sortiere Array:
    _ArraySort($aRetArr, 0, 0, 8, 0)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Gebe Array aus:
    _ArrayDisplay($aRetArr)

    [/autoit]


    Dann kannst du dir ganz einfach eine ersten 5 Einträge herausziehen.
    Natürlich könnte man es für diesen einfachen Anwendungsfall auch direkt die Datei nach den ersten 5 Zahlen durchsuchen aber dann benötigst du auch kein ArraySort mehr.

    Edit: Wenn es wirklich nur immer die ersten 5 (oder ähnliche) Einträge sein sollen dann war dein Ansatz gar nicht mal sooo verkehrt.
    So sollte es dann aber klappen:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $iTop = 5, $sDelimiter = '|' ; $Delimiter ist das Trennzeichen
    Global $iNum, $aRetArr[$iTop]

    [/autoit] [autoit][/autoit] [autoit]

    ; Öffne Datei:
    $hFile = FileOpen("songs.txt", 0)
    If $hFile = -1 Then
    MsgBox(0, "Fehler", "Konnte Datei nicht öffnen.")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Do
    $line = FileReadLine($hFile)
    If @error = -1 Then ExitLoop

    ; Bestimme linke Seite (Zahl) und rechte Seite (Interpret oder sowas) der Zeile
    $iNum = Int(StringLeft($line, StringInStr($line, $sDelimiter)))
    $sText = StringRight($line, StringLen($line) - StringInStr($line, $sDelimiter))

    ; Vergleiche die Zahl ob sie einer der ersten 5 Zahlen entspricht:
    For $i = 1 To $iTop
    If $iNum = $i Then $aRetArr[$i-1] = $sText
    Next
    Until 0

    [/autoit] [autoit][/autoit] [autoit]

    _ArrayDisplay($aRetArr)

    [/autoit]

    Einmal editiert, zuletzt von AspirinJunkie (4. September 2010 um 12:36)

  • Dieser Auszug aus der Hilfe sollte dir die Lösung bringen.

    Spoiler anzeigen
    [autoit]


    _ArrayDisplay($avArray, "$avArray VOR _ArraySort()")
    _ArraySort($avArray, 0, 0, 0, 0)
    _ArrayDisplay($avArray, "$avArray NACHDEM _ArraySort() Spalte 0 aufsteigend sortiert hat")
    _ArraySort($avArray, 0, 0, 0, 1)
    _ArrayDisplay($avArray, "$avArray NACHDEM _ArraySort() Spalte 1 aufsteigend sortiert hat")
    _ArraySort($avArray, 0, 0, 0, 2)
    _ArrayDisplay($avArray, "$avArray NACHDEM _ArraySort() Spalte 2 aufsteigend sortiert hat")

    [/autoit]

    MfG
    Der_Doc