ThomasJ: (PROGRAMMIERTECHNIK) 2-dimensionale Arrays sortieren. Wie?

hallo,

habe ein kleines problem mit einem array. es ist 2-dimensional und sieht etwa so aus:

---------------------                         ---------------------
  0   irgendwas                              0   irgendwas  
-------------------                         -------------------
  0   was anderes        so solls            0   verschieden
-------------------       werden...         -------------------
  1   noch eins                              0   was anderes
-------------------       -------\          -------------------
  1   immer noch                 \           1   endlich aus
-------------------               /         -------------------
  0   verschieden        -------/            1   immer noch  
-------------------                         -------------------
  1   endlich aus                            1   noch eins  
-------------------                         -------------------
  .   .... ...                               .   .... ...    
:     :             :                         :     :             :

jetzt würde ich gerne nach der spalte 1 sortieren, d.h. zuerst nuller, dann einser. im prinzip egal. hauptsache, dass die zweite spalte entsprechend mitsortiert wird. der einfache SORT befehl funktioniert nicht so recht, mit den anderen kann ich nicht so recht umgehen (was ist zb ein key?).

wie kriege ich das eingentlich hin? am liebsten würde ich übrigens die implementierten funktionen nutzen. falls jemand eine do-it-yourself-lösung weiss (zb mit eigener quick- oder bubblesort-funktion) ist das auch ok!

danke im voraus
thomas j. -der mit dem "lower-case"- :)

ps: was hält ihr von meinen "ascii-arts"? (vergeßt es :)

  1. hallo, thomas <lowercase>J</lowercase>.

    habe ein kleines problem mit einem array. es ist 2-dimensional und sieht etwa so aus:

    ---------------------                         ---------------------
      0   irgendwas                              0   irgendwas  
    -------------------                         -------------------
      0   was anderes        so solls            0   verschieden
    -------------------       werden...         -------------------
      1   noch eins                              0   was anderes
    -------------------       -------\          -------------------
      1   immer noch                 \           1   endlich aus
    -------------------               /         -------------------

    .....
    Also erstmal ist das NICHT 2-dimensional, bzw. geht so nicht, da an einem Index bzw. Key immmer nur ein Value stehen kann.
    Dieser kann allerdings selbst wieder ein Array sein, und dann ist es 2-dim.
    Also warum erzeugst Du Dein Array nicht so:
    $a[0] = array("'irgendwas","was anderes",....) ;
    $a[1] = array("noch eins","immer noch",....) ;
    oder auch:
    $n = 1; $a[$n][] = "nochwas" ;
    Nun kannst du ein einer Schleife alle Unterarrays sortieren. Das Äussere brauchst Du in diesem Fall eigentlich nicht sortieren.
    z.B:
      reset($a); while (list($n,$v) = each($a) ) { sort($v) }

    Hoffe, das ist etwa das was Du willst.

    ps: was hält ihr von meinen "ascii-arts"? (vergeßt es :)

    Wieso ? Sind doch sehr schön.

    MfG Enkel39

  2. <html><?PHP
    /*

    Hi thomas,

    Wenn ich dich richtig verstanden habe ist dein Array so definiert;
    */

    $feld= array( array(0,"irgendwas"),
                  array(0,"was anderes"),
                  array(1,"noch eins"),
                  array(1,"immer noch"),
                  array(0,"verschieden"),
                  array(1,"endlich aus")
                );

    // Zum Sortieren brauchste dann eine eigene Vergleichsfunktion,
    // die deine Array-struktur kennt

    function vergleich($a,$b)
    {
        if($a[0] > $b[0])
            return 1;

    if($a[0] < $b[0] )
            return -1;

    return 0;
    }

    // SORTIEREN
    usort($feld, vergleich);

    // Testausgabe
    for($n=0; $n< count($feld); $n++ )  
        echo $feld[$n][0]," ",$feld[$n][1],"<br>";

    /*

    ps: was hält ihr von meinen "ascii-arts"? (vergeßt es :)

    Die haben mir das Antwort leichtgemacht :-)

    Viele Gruesse,

    Carsten

    */ ?> </html>

    1. function gruss($name) { echo "hallo $name!"; }

      gruss("carsten");

      /* ja, richtig, so grüßen sich PHP-ler <fg> */

      deine Lösung funktioniert bestens, danke!
      doch da habe ich immer noch zwei fragen (weil ich merke, dass du dich gut auskennst :)

      1. wie kann ich "rückwärts" sortieren? oder das array nach dem sortieren "umdrehen"? (nutze PHP3)

      2. nur, falls Du noch lust und zeit hast (die lösung benötige ich nicht, aber würde mich sehr interessieren!)...

      was ist, wenn ich ein folgendes array habe:

      -----------------------------
      37827   0   irgendwas  
      ---------------------------
      37219   0   was anderes
      ---------------------------
      11284   1   noch eins  
      ---------------------------
      12783   1   immer noch  
      ---------------------------
      64783   0   verschieden
      ---------------------------
      36235   1   endlich aus
      ---------------------------
      .....   .   .... ...    
      :       :     :             :

      so... du kannst dir die frage schon denken?
      ich möchte nun nach der zweiten spalte sortieren! geht das ohne weiteres?

      eigentlich möchte ich darauf hinaus, dass die lösung evtl. flexibel sein könnte, d.h. z.B. eine funktion, die als parameter das zu sortierende array erwartet, und den spaltenindex, z.b.

      function mySuperbSort($_theArray, $_sortIndex) {
        /* und jetzt? */
      }

      und dann aufruf für oberes array, um nach zweiter spalte zu sortieren:

      mySuperbSort($myArray, 1);

      danke für deine mühe!
      gruß,
      thomas j. (immer noch mit lower-case);

      1. <html><?PHP
        /* OK, der erste Versuch war wohl ein Fehlstart. Habe die Frage trotz
           der tollen Grafik leider völlig falsch verstanden.
           Obwohl ich mich natürlich nicht auskenne noch ein Versuch..
        */
        $enc=' .,-!?()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ;
        $dec='VWX)hJMij.,YZ-lmKLnode!abgf PFuDEckGHqtvwyxzABCrsINOQRpSTU?(' ;
        function msg ($s) { global $enc,$dec ;
           print(strtr($s,$enc,$dec)); echo "<br>\n"; }
        msg('?ptgnzAth)z!tmlz!tbb');
        msg('Vlgz!ntVU)ngz!nktApkkt)z!tpwz!b');

        /* Beide Fragen lassen sich durch eine modifizierte Vergleichsfunktion
           lösen, fast alle anderen auch. (z.B. sortieren nach mehreren Feldern) */
        $sortcol=1 ;     // Spalte nach der sortiert werden soll
        $sortrev=false ; // Wenn absteigend sortiert werden soll, auf true setzen

        function vergleich2($a,$b) { global $sortrev,$sortcol ;
          if($a[$sortcol] == $b[$sortcol]) return 0;
          if($a[$sortcol] <  $b[$sortcol]) $r=-1 ; else $r=1 ;
          if($sortrev) return -r ; else return r ;
        }

        // SORTIEREN etc. wie in der vorigen Antwort
        // usort($feld, vergleich2);

        msg('y)ktsNwOEN)nNEnNtykAng39');
        ?></html>

      2. <html><?PHP
        /* Sorry, in der vorigen Antwort fehlen 2 $ vor den return r/-r
           Wenn man sortord auf +/-1 für auf/absteigend setzt gehts noch eleganter;
           siehe englisches PHP-Manual.array.usort (s.176)
        */
        $sortcol=  1;  // Spalte nach der sortiert werden soll
        $sortord= -1;  // -1 absteigend / +1 aufsteigend

        function vergleich3($a,$b) { global $sortcol,$sortord  ;
          if($a[$sortcol] == $b[$sortcol]) return 0;
          return ($a[$sortcol] > $b[$sortcol]) ? $sortord : -$sortord ;
        }

        msg('Vz!lnknktKqnkmtklz!bbb');
        ?></html>

      3. Hi thomas j.

        doch da habe ich immer noch zwei fragen [...]

        das hatte ich befürchtet ;-)

        1. wie kann ich "rückwärts" sortieren? oder das array nach dem sortieren "umdrehen"? (nutze PHP3)
        2. nur, falls Du noch lust und zeit hast (die lösung benötige ich nicht, aber würde mich sehr interessieren!)...
          [...]  ich möchte nun nach der zweiten spalte sortieren! geht das ohne weiteres?

        ....uff, sie ist nicht dabei.

        Na klar geht das beides und zwar ziemlich einfach, du brauchst nur deine Vergleichsfunktion anzupassen:

        Rückwarts sortieren:

        function vergleich($a,$b)
        {
            if($a[0] < $b[0])    // > und < getauscht !
                return 1;

        if($a[0] > $b[0])
                return -1;

        return 0;
        }

        Beliebige Spalte sortieren:

        $spalte=1;     // hier Wunschspalte zuweisen

        function vergleich($a,$b)
        {
            global $spalte;

        if($a[$spalte] > $b[$spalte])
                return 1;

        if($a[$spalte] < $b[$spalte] )
                return -1;

        return 0;
        }

        Der Rest bleibt jeweils gleich, d.h. sortieren mit usort($feld,vergleich);

        ...also sieht dein SuperSort so aus:

        function mySuperbSort($theArray, $sortIndex)
        {
            global $spalte;
            
            $spalte=$sortIndex;
            usort($theArray,vergleich);
        }

        Das mit der globalen Variable $spalte ist natürlich etwas häßlich, aber erstmal das einfachste. Die
        Funktion vergleich() wird ja vom Sortieralgorithmus usort() aufgerufen, auf die Aufrufparameter hat
        man daher keinen Einfluß, einfach mitübergeben geht also nicht.

        Diesmal übrigens alles in ungetestet - fehlende $ bitte ergänzen.

        viel Spass beim ausprobieren,

        Carsten