Mehrdimensionales Array sortieren?

Begonnen von Cramp, 03 Januar 2005, 15:54:35

⏪ vorheriges - nächstes ⏩

0 Mitglieder und 1 Gast betrachten dieses Thema.

Cramp

Hallo!

Ich würde gerne wissen wie ich folgendes Array sortieren kann:

      while($rs=$this->db->sql_fetchrow($stmt)){
         $landList[$i][0]=$rs['idland'];
         $landList[$i][1]=$rs['name'];
         $landList[$i][2]=$rs['language'];
         $i++;
      }

Es soll nach "idland" sortiert werden, also $landList[$i][0], und wenn es geht danach auch noch nach [1] und [2]...

Am Ende sollte die Ausgabe des Arrays über foreach ($landlist as $liste)
Etwa so aussehen:

1 Germany          english
1 Deutschland     german
2 Italy                 english
2 Italy                german
...

Weiß einer die Lösung?

Gruß

Cramp

jubilee

Hallo !
Besser wäre so :
Zitat
while($rs=$this->db->sql_fetchrow($stmt)){
         $landList['idland'][$i]=$rs['idland'];
         $landList['name'][$i]=$rs['name'];
         $landList['language'][$i]=$rs['language'];
         $i++;
      }

Dann sortieren über
php-Funktion array_multisort();

array_multisort($landList['idland'], SORT_ASC, SORT_NUMERIC, $landlist['name'], SORT_ASC, SORT_STRING, $landList['language'], SORT_ASC, SORT_STRING);


probier mal.
Ist aber von mir nicht gestestet.
MfG
jubilee

Cramp

Klappt leider noch nicht... aber ich habe auch gelogen... Das Array wird nicht per foreach... ausgelesen! Sorry!

Hier ist nochmal ein wenig mehr Code:
Auszug aus der Funktion zum Auslesen der Länder:

$sSql="SELECT * FROM ".$this->prefix."_topmusic_land_lang";

$stmt=$this->db->sql_query($sSql);
$i=0;
while($rs=$this->db->sql_fetchrow($stmt)){
$landList['idland'][$i]=$rs['idland'];
$landList['name'][$i]=$rs['name'];
$landList['language'][$i]=$rs['language'];
$i++;
}
array_multisort($landList['idland'], SORT_ASC, SORT_NUMERIC, $landList['name'], SORT_ASC, SORT_STRING, $landList['language'], SORT_ASC, SORT_STRING);
$this->db->sql_freeresult($stmt);
return $landList;


Auszug aus der Anzeige-Funktion:

for($i=0;$i<count($landList);$i++){
$land['idland']=$landList['idland'][$i];
$land['language']=$landList['language'][$i];
$land['name']=$landList['name'][$i];
echo " <tr>\n";
echo " <td>".$land['idland']."</td><td>&nbsp;</td>\n";
echo " <td>".$land['language']."</td><td>&nbsp;</td>\n";
echo " <td>".$land['name']."</td><td>&nbsp;</td>\n";
echo " <td><a href=\"admin.php?op=topmusic&action=editLand&idland=".$land['idland']."\">"._TOPMUSIC_EDIT."</td><td>&nbsp;</td><td><a href=\"javascript:delItem(".$land['idland'].");\">"._TOPMUSIC_DELETE."</a></td>\n";
echo " </tr>\n";
$i++;
}


Hintergrund dazu:

..._land:
fields: "idland"

..._land_lang:
fields: "idland"
          "name"
          "language"

Es existieren zwei Tabellen für die Speicherung der Länder. Notwendig weil das entsprechende Modul eine Sprachunterstützung hat. Sprich beim Aufruf des Mx in englisch wird beispielsweise die englische Länderbezeichnung verwendet. Für die Administration möchte ich aber alle Sprachen angezeigt haben, ohne das Mx komplett auf eine andere Sprache zu stellen.
Die Tabelle ..._land dient nur der Speicherung der ID des Landes, die Bezeichnung in der jeweiligen Sprache steht dann in der Tabelle ..._land_lang. Verknüpft durch "idland". Ich habe also beispielsweise in der Tabelle ..._land_lang den Eintrag "1 Deutschland german", "1 Germany english", "2 England german", "2 England english", usw....

Wenn ich das Script so wie oben beschrieben ausführe gibt es mir genau zwei Einträge zurück. Das ist zuwenig!

Ich habe ein wenig rumprobiert, komme aber auf keinen grünen Zweig.
Beispielsweise habe ich die SQL Anweisung mir ORDER BY modifiziert, um das Sortieren vor der Speicherung in das Array vorzunehmen, ist aber kläglich gescheitert. Das Script "vergisst" einzelne Einträge, vermutlich weil durch die Funktion sql_fetchrow der Zeiger nicht jedes Element der Datenbank anspricht.

Ich meine es ist zwar nicht schlimm, daß ich ohne Sortierung ein kleines Durcheinander auf dem Screen habe, aber schöner wäre es schon sortiert...

Vielleicht kann man die Funktion oder das Array ja noch umbauen, aber ich habe da irgendwie eine kreative Blockade... weiß keinen Rat, vielleicht jemand von euch?

PS: Handelt sich übrigens um das nuke-modul "TopMusic", welches ich um ein paar Features ergänzen möchte...


Biker

Detektei Martin - wir bringen Licht ins Dunkle!

jubilee

Hallo !
das hier
Zitatfor($i=0;$i<count($landList);$i++){
ist verkehrt. Bei diesem Arrayaufbau hat $landlist nur genau 3 Einträge
und zwar $landlist['name'], $landlist['idland'] und $landlist['language']
Richtifg lauten müsste das :
Zitatfor($i=0;$i<count($landList['idland']);$i++){
Probier damit mal
MfG
jubilee

Cramp

Klappt schon besser! Danke! Hätte ich eigentlich selbst drauf kommen müssen! Aber ich muß gestehen, daß mir da wohl ein wenig abstraktes Denkvermögen fehlt.

Folgende Ausgabe erreiche ich mit diesem Aufruf:
   
1   german   Deutschland   Edit   Löschen
1   english   Germany   Edit   Löschen
2   german   England   Edit   Löschen
3   english   USA   Edit   Löschen
3   german_du   USA   Edit   Löschen
4   german_du   Italien   Edit   Löschen
5   english   France   Edit   Löschen
5   german_du   Frankreich   Edit   Löschen

Wenn man das nun mit den Datenbank Einträgen vergleicht fehlen allerdings wieder ein paar Einträge:
Datenbank:
1 german Deutschland
2 german England
1 english Germany
3 english USA
3 german USA
2 english England
1 german_du Deutschland
2 german_du England
3 german_du USA
5 german Frankreich
5 english France
5 german_du Frankreich
4 german Italien
4 english Italy
4 german_du Italien


Ich glaube das liegt an array_multisort. Wenn ich mich nicht irre, fasst die Funktion gleiche Felder zusammen, oder so ähnlich. Würde zumindest erklären, warum maximal zwei Sprachen pro Land aufgeführt werden. Bei England ist das Feld "name" in allen drei Sprachen gleich, deshalb erscheint es nur einmal.
Der einzige Fehler in der Theorie ist, daß bei Italien der englische Eintrag "Italy" fehlt... Und das ist doch sehr seltsam, oder?

Ich denke, daß könnte man beispielsweise mit einem weiteren Feld in der Tabelle beheben, ich denke da an "ID" auto_increment. Damit wäre ja ein "Unique-Index" geschaffen, der pro Eintrag nur einmal vorkommt...
Oder habt ihr noch eine andere Idee?


jubilee

#6
Hallo !
ZitatIch glaube das liegt an array_multisort. Wenn ich mich nicht irre, fasst die Funktion gleiche Felder zusammen, oder so ähnlich
Öhhh ....
Glaub ich nicht. Hab jedenfalss nix dergleichen gelesen.
Ich weiss, das es Probleme bei leeren indices geben kann, aber zusammenfassen
sollte das multisort eigentlich nicht.
Zitat
array_multisort() wird zum Sortieren von entweder mehreren Arrays auf einmal, oder eines multidimensionalen Arrays (entsprechend einer von mehreren Dimensionen) benutzt. Bei der Sortierung werden die Schlüsselassoziationen beibehalten.
Die angegebenen Arrays werden als Spalten einer Tabelle behandelt, welche nach Reihen sortiert werden - ähnlich der SQL Klausel ORDER BY. Das erste Array ist auch das erste in der Sortierreihenfolge. Die in diesem Array gleichen Zeilen (Werte) werden anhand des nächsten angegebenen Arrays sortiert, usw.
Die Struktur der Argumente ist etwas ungewöhnlich, aber flexibel. Das aller erste Argument muss ein Array sein. Die nachfolgenden Argumente können entweder ein Array oder eines der folgenden Sortierflags sein.
Es kann nur ein Sortierflag des selben Typs nach jedem Array spezifiziert werden. Sortierflags nach einem Array Argument gelten nur für dieses Array, und werden vor jedem neuen Array Argument zu den Defaultflags SORT_ASC und SORT_REGULAR zurückgesetzt.

??
Als Idee kann ich nur anbieten, die Datenbankausgabe gleich via ORDER BY FELD1, FELD2, FELD3 ASC zu sortieren.
MfG
jubilee

Cramp

Oh Mann!

Soviel Theater um einen winzigen Fehler:

in der for($i=0;$i<count$landList['idland'];$i++) - Schleife habe ich am Ende ein weiteres $i++ stehen (siehe Codeauszüge oben), und wunder mich warum zu wenig Daten ausgegeben werden! Zu dämlich!

Also für alle zur Beruhigung: die angegebene Variante mit array_multisort() funktioniert sehr gut! Ebenfalls funktioniert die Sortierung über ORDER BY in der SELECT Anweisung.

Auf jeden Fall Danke für die ganze Hilfe und verschwendete Zeit... man sollte seinen eigenen Code schon noch lesen können...

*g*

Gruß

Cramp

jubilee

Hallo !
Zitatin der for($i=0;$i<count$landList['idland'];$i++) - Schleife habe ich am Ende ein weiteres $i++ stehen (siehe Codeauszüge oben),
Jetzt wo Du es schreibst, seh ich es auch  :o
Hab ich vorher aber auch überlesen ....
MfG
jubilee