Array aus Array neu sortiert

  • ich habe 2 sql tabellen.
    in der einen sind kategorien gespeichert in der anderen programme, die einer dieser kategorien zugeordnet sind.

    ich möchte jetzt die kategorien mit allen dazugehörenden programmen in mehreren spalten darstellen. allerdings maximal 25 pro spalte (abhängig von der höhe des fensters).
    kategorie 1 hat 13 einträge
    kategorie 2 hat 3 einträge
    kategorie 3 hat 3 einträge
    kategorie 4 hat 3 einträge
    kategorie 5 hat 0 einträge
    kategorie 6 hat 1 eintrag
    da auch jede kategorie einen eintrag benötigt muss pro kategorie 1 addiert werden.

    jetzt zu meiner frage. um den platz optimal auszunutzen will ich ein neues array erstellen, in dem die kategorien so geordnet sind, dass die
    anzahl nicht über 25 steigt, jedoch kategorien mit weniger programmeinträgen vorgezogen werden. im oberen beispiel also so:

    1. spalte
    kategorie 1 13 einträge + 1 für Kategorie
    kategorie 2 3 einträge + 1 für Kategorie
    kategorie 3 3 einträge + 1 für Kategorie
    kategorie 6 1 eintrag + 1 für Kategorie

    2. spalte
    kategorie 4 3 einträge + 1 für Kategorie

    kategorien ohne einträge sollen ans ende des arrays.

    bis jetzt hab ich schon mal die anzahl der programme unter jeder kategorie.

    [autoit]

    $MaxEntrys = ($Hoehe - 100)/20
    Dim $KatEntrys[$Kategories[0][0]+1][2]
    For $i = 1 To $Kategories[0][0] Step 1
    $ProgInKat = _DoSQL("SELECT id FROM Programs WHERE Kategorie = '"&$Kategories[$i][0]&"';")
    $KatEntrys[$i][0] = $ProgInKat[0][0] + 1
    $KatEntrys[$i][1] = $Kategories[$i][0]
    Next

    [/autoit]


    in $KatEntrys[$i][0] steht also die anzahl programme und in $KatEntrys[$i][1] der name der kategorie.

    das neue array muss ein 2d array sein, also genauso wie das ursprüngliche Kategories, das von einer sql-abfrage kommt. wie kann ich dieses array jetzt erstllen?

    für eure hilfe währe ich sehr dankbar.

  • Hi,

    mir geht es da genauso so wie GTA. Ich verstehe nicht ganz was Du erreichen willst *rätzel*

    also ne Liste, sortiert nach der Anzahl der Programme ausgeben, ist ja kein Problem, aber was willst Du mit dieser 25er-Regel erreichen? Sollen dann die Programme je Kategorie ausgegeben werden?


    oder meinst Du sowas hier: ???

    [autoit]


    $ProgInKat = _DoSQL("SELECT categories.category, count(programs.kid) As Anzahl FROM programs, categories WHERE programs.kid = categories.id group by categories.category order by Anzahl desc;","example.db")
    For $i = 1 To $ProgInKat[0][0] Step 1
    ConsoleWrite("Kategorie: "&$ProgInKat[$i][0]&" Anzahl: "&$ProgInKat[$i][1]&@LF)
    Next

    [/autoit]
  • @jonk

    das problem ist, daß ich mehr kategorien und programme habe, als in eine spalte gehen. das progrmmfenster ist 800x600. im mittleren bereich gehen ungefähr 5 spalten rein. hab mal zur erklärung ein bild angehängt. vieleicht kann man daran besser sehen, was ich bezwecken will.

    wie man sehen kann, wird die kategorie office in der ersten spalte angezeigt und ein programm aus dieser kategorie darunter. alle anderen werden in der nächsten spalte angezeigt. und genau das will ich so machen, dass die kategorien zusammen bleiben.
    die nächste kategorie spiele hat nur einen eintrag und würde somit noch in die erste spalte passen.
    also will ich das array so neu sortieren, dass der platz bestmöglichst ausgenutzt wird, wie bereits in meinem ersten post beschrieben.

    hoffe, dass es ein bisschen klarer ist, was ich bewirken will.

  • habe eine lösung gefunden. ist für einen programmierer bestimmt nicht die ideale lösung, funktioniert aber.

    [autoit]

    $MaxEntrys = ($Hoehe - 100)/20
    $TotalEntrys = 0
    Dim $KatEntrys[$Kategories[0][0]+1][2]
    Dim $KategoriesOrder[$Kategories[0][0]+1][1]
    For $i = 1 To $Kategories[0][0] Step 1
    $ProgInKat = _DoSQL("SELECT id FROM Programs WHERE Kategorie = '"&$Kategories[$i][0]&"';")
    $KatEntrys[$i][0] = $ProgInKat[0][0]+1
    $KatEntrys[$i][1] = $Kategories[$i][0]
    $TotalEntrys = $TotalEntrys + $KatEntrys[$i][0]
    Next

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

    $Cols = Round($TotalEntrys/$MaxEntrys)

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

    $Zaehler = $Kategories[0][0]
    For $x = 1 To UBound($KatEntrys,1)-1 Step 1
    If $KatEntrys[$x][0] = 1 Then
    $KategoriesOrder[$Zaehler][0] = $KatEntrys[$x][1]
    $KatEntrys[$x][0] = $KatEntrys[$Zaehler][0]
    $KatEntrys[$x][1] = $KatEntrys[$Zaehler][1]
    $Zaehler = $Zaehler - 1
    EndIf
    Next

    $z = 0
    For $i = 1 To $Cols Step 1
    $LfdProg = 0
    For $y = 1 To $Zaehler Step 1
    $LfdProg = $LfdProg + $KatEntrys[$y][0]
    If $KatEntrys[$y][1] = "" Then
    $LfdProg = $LfdProg - $KatEntrys[$y][0]
    ContinueLoop
    Else
    If $LfdProg <= $MaxEntrys Then
    $z = $z + 1
    $KategoriesOrder[$z][0] = $KatEntrys[$y][1]
    $KatEntrys[$y][1] = ""
    ElseIf $LfdProg > $MaxEntrys Then
    $LfdProg = $LfdProg - $KatEntrys[$y][0]
    EndIf
    EndIf
    Next
    Next

    [/autoit]

    habe jetzt aber noch einige frage. vieleicht kann mir ja einer von euch diese beantworten. wenn ich mir in der console das neue array anzeigen lasse, werden auch alle 9 kategorien in der neuen gewünschten reihenfolge angezeigt.

    ausgabe in der console:
    mit UBound($KategoriesOrder,1)-1 bekomme ich 9 angezeigt.
    mit $KategoriesOrder[0][0] bekomme ich garnichts angezeigt.
    sollte das nicht das gleiche sein?

    hab dann auch mal nachgesehen und das array, das von der sql-abfrage kommt überprüft.

    mit UBound($Kategories,1)-1 bekomme ich 1023 angezeigt.
    mit $Kategories[0][0] bekomme ich 9 angezeigt.

    sollte nicht auch hier bei beiden methoden das gleiche angezeigt werden? bin jetzt vollkommen verwirrt. kann mir das mal jemand erklären bitte.

    • Offizieller Beitrag

    Außer bei bestimmten Funktionen, wo die Anzahl der Elemente im $Array[0] bzw. $Array[0][0] hinterlegt wird, mußt du bei eigenen Array selbst einen Zähler führen, wenn du das möchtest.
    z.B.

    [autoit]

    $Array[0][0]=0
    For $i = 1 To $x
    ; Daten ermitteln
    $Array[1][$i] = $wert
    $Array[0][0] += 1 ; Zaehler um 1 erhöhen
    Next

    [/autoit]

    In deinem Beispiel sehe ich keine Wertzuweisung für "$KategoriesOrder[0][0]".

  • vielen dank für deine antwort.

    ich dachte beim erstellen eines arrays wird in array[0][0] automatisch die anzahl der elemente gespeichert.
    bleibt noch die frage, warum das array von der sql-abfrage mit ubound 1023 ausgiebt.

  • Hi Byte,

    das liegt daran, das der Array per default 1023 felder hat. Deswegen wird bei
    diesem Array die Anzahl der tatsächlichen Felder unter Array[0][0] abgelegt.

    Ich hatte mich überigens mal an einem anderen Ansatz versucht ... sind aber immer nur Monster bei herausgekommen ;)