Sortierung eines Arrays in PHP

DaSoMa

Mitglied
Hallo,

ich suche eine Lösung fü folgendes Problem:

Ich habe eine Array, das folgendermaßen aufgebaut ist:

array('a-shop'=>'500','b-shop'=>'600','c-shop'=>'500')

Nun sortiere ich das Array nach der Zahl, aufsteigend:

array('c-shop'=>'500','a-shop'=>'500','b-shop'=>'600')

Dazu verwende ich asort(). Soweit so gut - so kann ich mit dem Array prinzipiell leben, aber noch besser wäre, wenn ich beeinflussen könnte, dass "a-shop" auf position 0 ist und nicht "c-shop".

Optimal wäre also für mich, wenn das Array weiterhin nach der Zahl aufsteigend sortiert wäre, aber z.B. ein bestimmter shop immer oben ist, wenn er die gleiche zahl hat wie andere shops:

array('a-shop'=>'500','c-shop'=>'500','b-shop'=>'600')

Vielleicht kann mir jemand eine einfache Lösung aufzeigen, ansonsten würde ich sozusagen anfangen das Array aufzuspalten, um es dann einzeln zu sortieren und dann am Ende wieder zusammenführen.

Ciao
 
Hallo DoSoMa

Sei Dein Array $a. Dann würde ich das wie folgt lösen:

CODE array_multisort(array_values($a), SORT_DESC, array_keys($a), SORT_ASC, $a);


Das verändert direkt den Array $a. Das darfst Du so lesen: Sortiere den Array nach den Values Absteigend und in zweiter Linie nach den Schlüsseln aufsteigend. Nicht die einzige Lösung aber nur eine Zeile Code und sehr gut lesbar. Ungetestet.

lg

PS: lese gerade "nach der Zahl aufsteigend", hab mich verkuckt. Dann beides mal SORT_ASC
 
Hi Alain Aubert,
danke für diese Lösung - kannte ich in der Form noch nicht! Wieder was gelernt, allerdings kann ich die Version so nicht verwenden. In dem von mir geschilderten Fall würde das gut klappen, nun schaut mein Array in der Realität so aus, dass es mehrere Values mit "a" am Anfang gibt und der interessanteste Wert eben nicht der erste alphabetisch wäre, sondern der 3.

Wie dem auch sei - ich habe eine eigene Lösung entwickelt - vielleicht ist sie nicht grade elegant, aber sie erfüllt meinen Zweck. Vielleicht bringt es jemandem etwas oder noch besser - jemand hat eine bessere Variante.

Es gäbe also das Array:

Array (
[unwichtig1] => 429.90,
[unwichtig2] => 439.00
[unwichtig3] => 439.00
[unwichtig4] => 439.00
[wichtig5] => 439.00
[unwichtig6] => 440.00
[unwichtig7] => 444.98 )

Das Ziel war es, dass die Sortierung nach der Zahl weiterhin so bleibt - d.h. das kleinst nach oben. Aber es gibt einen Key, der wichtig ist und möglichst weit oben für den Besucher zu sehen sein soll - hier "wichtig5" genannt.
Das Ziel wäre also ein Array, dass so aussieht:

Array (
[unwichtig1] => 429.90,
[wichtig5] => 439.00
[unwichtig2] => 439.00
[unwichtig3] => 439.00
[unwichtig4] => 439.00
[unwichtig6] => 440.00
[unwichtig7] => 444.98 )

Meine Lösung:

CODE
asort($select['preise']);
$neuesa = $select['preise']; //Temporäres Array mit aktuellem unsortiertem Array
if (array_key_exists('wichtig5',$neuesa)) {
$zielpreis = $neuesa['wichtig5'];
$i=0;
$j=0;
$ziel = array();
$wichtig5position=0;
$ersteselement=0;
foreach($neuesa as $key => $value) {
if ($j==0) {
if ($zielpreis == $value) {
$ersteselement = $i;
$j++;
}
}
if ($key == 'wichtig5') {
$wichtig5position = $i;
}
$ziel[$i] = array($key=>$value);
$i++;
}
if ($wichtig5position>$ersteselement) {
$temp1 = $ziel[$wichtig5position];
$temp2 = $ziel[$ersteselement];
$ziel[$ersteselement]=$temp1;
$ziel[$wichtig5position]=$temp2;
$ziel1 = array();
foreach($ziel as $key => $value) {
foreach($value as $key1 => $value1) {
$ziel1[$key1]=$value1;
}
}
$select['preise'] = $ziel1; // Daten in den Namen des ursprünglichen Arrays zurückschreiben
}
}



Das Ergebnis:
Array (
[unwichtig1] => 429.90,
[wichtig5] => 439.00
[unwichtig3] => 439.00
[unwichtig4] => 439.00
[unwichtig2] => 439.00
[unwichtig6] => 440.00
[unwichtig7] => 444.98 )

Man sieht recht gut, dass das wichtige Element an der ersten Position ist - im Endeffekt wurde das Element was zuvor auf der ersten Position war, auf die alte Position des wichtigen Elements verschoben. Simpler Tausch.

Was noch cool wäre:
1. eine simplere Lösung
2. Vorgabe, welche Elemente wichtig sind:

So dass z.B. aus dem folgenden Array:

Array (
[unwichtig1] => 429.90,
[unwichtig2] => 439.00
[wichtig3] => 439.00
[unwichtig4] => 439.00
[wichtig5] => 439.00
[unwichtig6] => 440.00
[unwichtig7] => 444.98 )

So etwas wird:

Array (
[unwichtig1] => 429.90,
[wichtig3] => 439.00
[wichtig5] => 439.00
[unwichtig2] => 439.00
[unwichtig4] => 439.00
[unwichtig6] => 440.00
[unwichtig7] => 444.98 )


Vielleicht hat jemand eine Idee - ansonsten danke an Alain Aubert!

Mit freundliche Grüßen
 
Hi

Das ist eine Normalisierungs Frage. D.h. Array Sortierung ist böse. I.d.R. sollten die Daten so normalisiert in der Datenbank liegen, dass Du die Sortierung direkt in der Query machen kannst.

Ich mache das Beispiel ausserhalb der DB mit Deinem Array. Pro Memoria. String Keys für Arrays sind leicht riskant.

Wir haben bekannten Array $a. Zusätzlich sei $b = array(wichtig1,...wichtigN,unwichtig1+N, ...unwichtigN+M). Diese Array Values sind offensichtlich die Keys von $a, folglich ist jeder einzigartig.
Beachte, dass $b in einer Form vorliegen muss, sodass die Sortierung anhand der Keys zu den Werten führt, die Du haben möchtest.

Dann änderst Du die Datenstruktur von $a["someStingKey"] in $a[1] (1 ist dabei der Key von $b zu dem Wert someStingKey von $b. Damit kannst Du die erste Lösung von mir direkt wieder anwenden und die normalisierten Daten wie gewohnt nutzen. Wenn Du den ursprünglichen Key von $a ausgeben möchtest, dann machst $b[$keyFromAArray].

Fazit. Du normalisierst die String Keys in eine eigene Datenstruktur und gibst ihnen eigene Keys sodass Sortierung trivial wird.

Deinen Code hab ich nicht gelesen, ich ändere aus Prinzip die Datenstruktur da es schneller geht einen bekannten Algo für eine bekannte Datenstruktur zu implementieren als einen neuen für eine komische...
wink.gif
 
Zurück
Oben