[PHP] Array zerlegen und mit eigenen Regel sortieren



  • Hallo guten Tag!

    Ich bekomme viele Arrays die folgende Struktur haben

    Array
    (
        [0] => Array
            (
                [id] => 15
                [text] => 7 harald irgendwas anderes
            )
    
        [1] => Array
            (
                [id] => 19
                [text] => 5 stefan irgendwas anderes
            )
    
        [2] => Array
            (
                [id] => 17
                [text] => 1 berta irgendwas anderes
            )
    
        [3] => Array
            (
                [id] => 17
                [text] => 3 sabine irgendwas anderes
            )
    
        [4] => Array
            (
                [id] => 15
                [text] => 10 henning irgendwas anderes
            )
    )
    

    (Schreckliche Struktur, ich weiß! Ich kann es leider nicht ändern..)

    Die sollen in eine bestimmt Reihenfolge gebracht werden. Und zwar soll es so aussehen:

    5 stefan irgendwas anderes
    3 sabine irgendwas anderes
    10 henning irgendwas anderes
    7 harald irgendwas anderes
    1 berta irgendwas anderes
    

    Also Namen mit S als erstes und mit der ersten Zahl absteigend sortiert. Dann der Buchstabe H, wieder mit höchster Zahl am Anfang und dann absteigend. Dann andere Buchstaben..

    Ich habe mir jetzt überlegt, dass ich die einzelnen [text] per explode/Leerzeichen zerlege und anschließend die einzelnen Teile à la

    wenn(erster Buchstabe von Teil2 == 's')
      speichere Teil1, Teil2 und Rest in sammel_array_s
    wenn(erster Buchstabe von Teil2 == 'h')
      speichere Teil1, Teil2 und Rest in sammel_array_h
    usw.
    

    Anschließend den Teil1 von sammel_array_? per asort() absteigend sortieren. Danach alle sammel_array_? wieder zu einem zusammensetzen.

    Ich bin mir allerdings fast sicher, dass meine Idee nicht so richtig optimal ist - daher die Frage an euch, ob jemand vielleicht eine bessere (und vor allem schnellere) Lösung hat?

    Vielen Dank und schöne Grüße,
    Chris


  • Mod

    Einfach per usort sortieren und fertig.



  • Nach ein wenig Anlaufschwierigkeiten funktioniert es jetzt sehr gut und läuft auch sehr schnell! Danke für den Hinweis.



  • *Anlaufschwierigkeiten mit usort versteht sich...



  • Hm, ich hatte mich zu früh gefreut. Habe mich eben nochmal dran gesetzt und einen Fehler gefunden den ich nicht hinbekomme..

    Ich habe zwei verschiedene usort-Funktionen. Beide funktionieren alleine, leider aber nicht zusammen.

    cmp0 liefert:

    Array
    (
        [0] => [b]25[/b] forward
        [1] => [b]10[/b] forward
        [2] => [b]10[/b] regular
        [3] => [b]7[/b] regular
        [4] => [b]7[/b] auto
        [5] => [b]5[/b] forward
        [6] => [b]3[/b] regular
        [7] => [b]3[/b] forward
    )
    

    cmp1 liefert:

    Array
    (
        [0] => 7 [b]a[/b]uto
        [1] => 5 [b]f[/b]orward
        [2] => 10 [b]f[/b]orward
        [3] => 25 [b]f[/b]orward
        [4] => 3 [b]f[/b]orward
        [5] => 7 [b]r[/b]egular
        [6] => 10 [b]r[/b]egular
        [7] => 3 [b]r[/b]egular
    )
    

    Beide korrekt!

    Ich würde die aber gerne kombinieren.. Es soll so aussehen:

    Array
    (
        [0] => 7 auto
        [1] => 25 forward
        [2] => 10 forward
        [3] => 5 forward
        [4] => 3 forward
        [5] => 10 regular
        [6] => 7 regular
        [7] => 3 regular
    )
    

    Hier ist mein Beispielscenario:

    <?php
    	echo'<pre>';
    
    	$the_array = array();
    	$the_array[] = explode(' ', '10 regular');
    	$the_array[] = explode(' ', '10 forward');
    	$the_array[] = explode(' ', '3 regular');
    	$the_array[] = explode(' ', '5 forward');
    	$the_array[] = explode(' ', '25 forward');
    	$the_array[] = explode(' ', '3 forward');
    	$the_array[] = explode(' ', '7 regular');
    	$the_array[] = explode(' ', '7 auto');
    
    	shuffle($the_array);
    
    	$before = $the_array;
    	foreach($before as $id => $value)
    		$before[$id] = implode(' ', $before[$id]);
    	print_r($before);
    
    	// sortiert die zahlen absteigend
    	function cmp0($a, $b) {
    		if($a[0] < $b[0]) return  1;
    		if($a[0] > $b[0]) return -1;
    		return 0;
    	}
    
    	// sortiert die buchstaben aufsteigend
    	function cmp1($a, $b) {
    		if($a[1] > $b[1]) return 1;
    		if($a[1] < $b[1]) return -1;
    		return 0;
    	}
    
    	usort($the_array,'cmp0');
    //	usort($the_array,'cmp1');
    
    	foreach($the_array as $id => $value)
    		$the_array[$id] = implode(' ', $the_array[$id]);
    	print_r($the_array);
    
    	echo'</pre>';
    ?>
    

    Hat jemand eine Idee?



  • Dann kombinier sie doch einfach:

    Dein Code:

    // sortiert die zahlen absteigend
        function cmp0($a, $b) {
            if($a[0] < $b[0]) return  1;
            if($a[0] > $b[0]) return -1;
            return 0;
        }
    
        // sortiert die buchstaben aufsteigend
        function cmp1($a, $b) {
            if($a[1] > $b[1]) return 1;
            if($a[1] < $b[1]) return -1;
            return 0;
        }
    

    Der neue Code:

    // sortiert die zahlen absteigend
        function cmp($a, $b) {
            if($a[0] < $b[0]) return  1;
            if($a[0] > $b[0]) return -1;
    
            if($a[1] > $b[1]) return 1;
            if($a[1] < $b[1]) return -1;
    
            return 0;
        }
    
        usort($the_array,'cmp');
    


  • Verstehst du eigentlich was der Fehler war?



  • hi könig,

    hab das mal ausprobiert. Aber eigentlich ist es klar, dass es nicht funktioniert, da die returns beim index[0] - also bei den ersten beiden ifs schon aufgerufen werden.
    Habe es dennoch eben probiert - das hier ist der Output:

    Array
    (
        [0] => 25 forward
        [1] => 10 forward
        [2] => 10 regular
        [3] => 7 auto
        [4] => 7 regular
        [5] => 5 forward
        [6] => 3 forward
        [7] => 3 regular
    )
    

    Es ist nur nach index[0] sortiert. Also für mich keine Lösung..

    Es soll so aussehen:

    Array
    (
        [0] => 7 auto
        [1] => 25 forward
        [2] => 10 forward
        [3] => 5 forward
        [4] => 3 forward
        [5] => 10 regular
        [6] => 7 regular
        [7] => 3 regular
    )
    

    Trotzdem Danke



  • Dann hast dus noch nicht gerafft. Du sortierst erst nach index = 0 und dann verwirfst du dioe reihenfolge komplett mit dem zweiten usort aufruf. Du musst beide Vergleiche in einer Strategie zusammenfassen damit du die reihenfolge hinkriegst...

    Dann dreh die zwei Teile um und vergleiche erst index = 1 und danach den index = 0

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


  • Hm ja ne, hatte es nicht gerafft. Danke für den Hinweis, ich geh mich schämen.


Anmelden zum Antworten