1. Sortierung über array_intersect()
Die Funktion array_intersect($arr1, $arr2) kann zweckentfremdet werden, um bestimmte ungewöhnliche Sortierungen von Arrays zu erzeugen. Diese Sortierungen müssen in einem Array gespeichert sein und sollten daher nicht sonderlich viele Elemente umfassen. Das Sortierungsarray mit der vorgegebenen Reihenfolge muss als erstes Array ($arr1) an array_intersect() übergeben werden. Das zweite Array ist das zu sortierende. Alle Werte aus $arr2, die nicht Teil des Sortierungsarrays sind, gehen verloren.
<?php $arr = array('II', 'IV', 'a', 'III', 'b', 'V', 'VI', 'c', 'I'); $sortOrder = array('I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'); $sorted = array_intersect($sortOrder, $arr); var_dump($sorted); ?>
array(6) { [0]=> string(1) "I" [1]=> string(2) "II" [2]=> string(3) "III" [3]=> string(2) "IV" [4]=> string(1) "V" [5]=> string(2) "VI" }
Auch Duplikate gehen bei der Anwendung von array_intersect($arr1, $arr2) verloren.
<?php $arr = array('II', 'II', 'II', 'II', 'IV', 'a', 'III', 'b', 'V', 'VI', 'c', 'I'); $sortOrder = array('I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'); $sorted = array_intersect($sortOrder, $arr); var_dump($sorted); ?>
array(6) { [0]=> string(1) "I" [1]=> string(2) "II" [2]=> string(3) "III" [3]=> string(2) "IV" [4]=> string(1) "V" [5]=> string(2) "VI" }
2. Werte beibehalten, die nicht Teil der vorgegebenen Ordnung sind
Will man, dass alle Werte aus dem zu sortierenden Array erhalten bleiben (also auch die, die nicht im Array mit der vorgegebenen Reihenfolge stehen), dann kann nach array_intersect() noch eine Kombination aus array_diff() und array_merge() angewendet werden. Über array_diff($arr1, $arr2) wird die Differenz von $arr1 und $arr2 bestimmt, also alle Werte, die in $arr1, aber nicht in $arr2 enthalten sind. Entsprechend ergibt bei einem Sortierarray $sortOrder und einem zu sortierenden Array $arr nun array_diff($arr, $sortOrder) alle Elemente aus $arr, die nicht in der Sortiervorgabe $sortOrder enthalten sind. Diese können über array_merge($arr1, $arr2) zu einem anderen Array hinzugefügt werden — in diesem Fall zum Ergebnis der Sortierung. So bleiben auch die Werte erhalten, die nicht Teil der Sortiervorgabe sind.
<?php $arr = array('II', 'c', 'IV', 'a', 'III', 'b', 'V', 'VI', 'I'); $sortOrder = array('I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'); $sorted = array_intersect($sortOrder, $arr); $remaining = array_diff($arr, $sortOrder); $both = array_merge($sorted, $remaining); var_dump($both); ?>
array(9) { [0]=> string(1) "I" [1]=> string(2) "II" [2]=> string(3) "III" [3]=> string(2) "IV" [4]=> string(1) "V" [5]=> string(2) "VI" [6]=> string(1) "c" [7]=> string(1) "a" [8]=> string(1) "b" }
3. Funktion mit verschiedenen Sortiermöglichkeiten
Nachfolgend wird eine Funktion definiert, die ein Array $arr anhand einer Sortiervorgabe $order sortiert. Die Funktion bietet folgende Parameter:
- $arr: Das zu sortierende Array.
- $order: Ein Array mit der vorgegebenen Reihenfolge.
- $asc: Gibt an, ob entsprechend der Reihenfolge aus $order aufsteigend (true) oder absteigend (false) sortiert werden soll. (Standard: true/aufsteigend)
- $keepRemainings: Gibt an, ob Elemente übernommen werden sollen, die nicht in $order enthalten sind. (Standard: true)
- $orderRemainings: Gibt an, ob die übrig gebliebenen Elemente mit sort() sortiert werden sollen. (Standard: false)
- $orderRemainingsAsc: Gibt an, ob die übrig gebliebenen Elemente aufsteigend (true) oder absteigend (false) sortiert werden sollen. (Standard: true/aufsteigend)
Als wesentliche Funktionen kommen hier gegenüber den vorherigen Beispielen nur sort() und rsort() hinzu, welche ein Array aufsteigend (sort()) bzw. absteigend (rsort()) anhand seiner Werte sortieren.
<?php function sortByOrder($arr, $order, $asc=true, $keepRemainings=true, $orderRemainings=false, $orderRemainingsAsc=true) { // Falls entsprechend der Ordnung in $order _absteigend_ sortiert werden soll, // wird die Ordnung darin umgedreht if (!$asc) { $order = array_reverse($order); } // Sortierung anhand von $order durchführen $sorted = array_intersect($order, $arr); if ($keepRemainings) { // Falls die übrig gebliebenen Elemente übernommen werden sollen, // werden diese berechnet $remaining = array_diff($arr, $order); if ($orderRemainings) { if ($orderRemainingsAsc) { // Falls die übrig gebliebenen Elemente sortiert werden sollen // und das aufsteigend wird einmalig sort() angewendet (aufsteigende // Sortierung eines Arrays) sort($remaining); } else { // Falls analog absteigend rsort() (absteigende Sortierung eines Arrays) rsort($remaining); } } } else { $remaining = array(); } $both = array_merge($sorted, $remaining); return $both; } // Beispielarray $arr = array('II', 'c', 'IV', 'a', 'III', 'b', 'V', 'VI', 'I'); // Sortiervorgabe $sortOrder = array('I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'); // entsprechend der Ordnung aufsteigend sortieren, übrig gebliebene Elemente am Ende anfügen var_dump( sortByOrder($arr, $sortOrder) ); // entsprechend der Ordnung absteigend sortieren, übrig gebliebene Elemente nicht übernehmen var_dump( sortByOrder($arr, $sortOrder, false, false) ); ?>
array(9) { [0]=> string(1) "I" [1]=> string(2) "II" [2]=> string(3) "III" [3]=> string(2) "IV" [4]=> string(1) "V" [5]=> string(2) "VI" [6]=> string(1) "c" [7]=> string(1) "a" [8]=> string(1) "b" } array(6) { [0]=> string(2) "VI" [1]=> string(1) "V" [2]=> string(2) "IV" [3]=> string(3) "III" [4]=> string(2) "II" [5]=> string(1) "I" }