[gelöst] PHP :: usort - Sortierung behalten
Eingetragen von headkit (514)
am 15.09.2009 - 07:19 Uhr in
am 15.09.2009 - 07:19 Uhr in
hi leute!
ich habe ein mehrdimensionales array, dessen unterarrays objekte enthaten:
allBtns = [ [obj1, obj2,...], [objA, objB,...], ... ]
das möchte ich mittels USORT sortieren.
prinzipiell geht das auch, nur "verliere" ich diese sortierung wieder, und verstehe nicht, wieso.
<?php
//sortiert array
if(sizeof($allBtns) > 0) {
foreach ($allBtns as $subArr) {
if(sizeof($subArr) > 1) usort($subArr, "cmp_btnID");
}
}
// referenzfunktion
function cmp_btnID($a, $b)
{
if($a->field_button_id && $b->field_button_id) {
$varA = (int)$a->field_button_id[0][value];
$varB = (int)$b->field_button_id[0][value];
echo ' <!-- '.$varA.' / '.$varB." -->\n";
/*if ($varA == $varB) {
return 0;
}
return ($varA < $varB) ? -1 : 1;*/
return strnatcasecmp($varA,$varB);
}
}
// überprüfung
foreach ($allBtnsas $sub) {
echo '-> danach: ';
foreach ($sub as $element) {
echo $element->field_button_id[0][value].', ';
}
}
/*
--- AUSGABE ---
2, 1, -> 1, 2,
1, 3, 2, -> 1, 2, 3,
-> danach: 2, 1,
-> danach: 1, 3, 2,
*/
?>
nach der sortierung zeigt mir noch die alte reihenfolge an. wieso das?
danke!
- Anmelden oder Registrieren um Kommentare zu schreiben
usort und verschachtelte Arrays
am 15.09.2009 - 07:42 Uhr
Moin.
Du möchtest das "oberste" Array verändern, tust dies jedoch nicht. Du veränderst eine Kopie der jeweiligen Kind-Arrays.
Versuch mal Folgendes (ungetestet):
<?php
// Das 1. sizeof ist überflüssig.
foreach ($allBtns as $key => $subArr) {
usort($allBtns[$key], "cmp_btnID"); // Das 2. sizeof sollte auch überflüssig sein.
}
function cmp_btnID($a, $b)
{
if ($a->field_button_id && $b->field_button_id) {
$varA = (int)$a->field_button_id[0]['value']; // String in ' einbetten. Ansonsten vermutet PHP eine Konstante!
$varB = (int)$b->field_button_id[0]['value']; // String in ' einbetten. Ansonsten vermutet PHP eine Konstante!
return strnatcasecmp($varA, $varB);
}
}
// überprüfung
foreach ($allBtns as $sub) {
echo '-> danach: ';
foreach ($sub as $element) {
echo $element->field_button_id[0]['value'] . ', ';
}
}
?>
hth,
Stefan
--
sei nett zu Deinem Themer
neinnein, ich möchte das
am 15.09.2009 - 08:24 Uhr
neinnein, ich möchte das oberste array so lassen, die objekte in den subarrays aber sortieren.
Stefan hat schon
am 15.09.2009 - 08:39 Uhr
Stefan hat schon Recht.
<?php
if(sizeof($allBtns) > 0) {
foreach ($allBtns as $subArr) { // Das aktuelle Element aus $allBtns wird nach $subArr kopiert
if(sizeof($subArr) > 1) usort($subArr, "cmp_btnID"); // Die Kopie wird sortiert
} // In $allBtns liegt noch das unsortierte Original.
}
?>
Ich finde folgende Lösung etwas schöner als die von Stefan vorgeschlagene:
<?php
//sortiert array
if(sizeof($allBtns) > 0) {
foreach (array_keys($allBtns) as $key) {
usort($allBtns[$key], "cmp_btnID");
}
}
?>
Oder auch
<?php
//sortiert array
if(sizeof($allBtns) > 0) {
foreach ($allBtns as &$subArr) {
usort($subArr, "cmp_btnID");
}
unset($subArr); // Aufgrund eines obskuren Bugs in PHP notwendig
}
?>
--
Array
am 15.09.2009 - 08:48 Uhr
neinnein, ich möchte das oberste array so lassen, die objekte in den subarrays aber sortieren.
Ja, genau.
Du musst jedoch auch die Werte (genau das sind nämlich die Unterarrays) im obersten Array auch aktualisieren.
Momentan tust Du Folgendes:
a (Array)
- a1 (Unterarray)
- a2 (Unterarray)
...
--> sortiere innerhalb einer Kopie von a1
--> sortiere innerhalb einer Kopie von a2
...
--> gib a aus
Du hast jetzt zwar sortiert, jedoch hat sich die Veränderung überhaupt nicht auf das Ursprungsarray ausgewirkt.
Also musst Du Folgendes machen:
a (Array)
- a1 (Unterarray mit Schlüssel 1)
- a2 (Unterarray mit Schlüssel 1)
...
--> sortiere innerhalb von a[1]
--> sortiere innerhalb von a[2]
...
--> gib a aus
Damit schlägt sich die Änderung auch auf das Ursprungsarray nieder und Du kannst die Veränderung dort auch sehen.
hth,
Stefan
--
sei nett zu Deinem Themer
danke erstmal für die
am 15.09.2009 - 08:50 Uhr
danke erstmal für die unterstützung.
eventuell müsste ich noch nen kaffee nehmen, aber ich seh echt nicht den unterschied, warum in meiner version eine kopie sortiert wird und in eurer das original...
und wofür war noch mal das & vor dem $...
*gähn!!*
o.k. erstmal coffeeeee
__
edit: ups, da war ja noch jemand schneller...
usort
am 15.09.2009 - 08:52 Uhr
<?php
//sortiert array
if(sizeof($allBtns) > 0) {
foreach (array_keys($allBtns) as $key) {
usort($allBtns[$key], "cmp_btnID");
}
}
?>
Ungünstig, da ein zusätzlicher Aufruf von
array_keys
gemacht werden muss.<?php
//sortiert array
if(sizeof($allBtns) > 0) {
foreach ($allBtns as &$subArr) {
usort($subArr, "cmp_btnID");
}
unset($subArr); // Aufgrund eines obskuren Bugs in PHP notwendig
}
?>
Da bin ich mir nicht sicher, ob das überhaupt so funktioniert. Kann aber.
Das
sizeof
wird auch hier nicht benötigt. Wenn$allBtns
keine Elemente enthält, wird der Code in derforeach
Schleife auch nicht ausgeführt.hth,
Stefan
--
sei nett zu Deinem Themer
ach so, weil das array in
am 15.09.2009 - 08:55 Uhr
ach so, weil das array in der forech-schleife zum bearbeiten nur kopiert wird...!
wäre es denn innerhalb einer for-schleife anders?
<?php
if(sizeof($allBtns) > 0) {
for ($i=0; $i<= sizeof($allBtns)-1; $i++){
if(sizeof($allBtns[$i]) > 1) usort($allBtns[$i], "cmp_btnID");
}
}
?>
stBorchert schrieb traxer
am 15.09.2009 - 09:27 Uhr
und wofür war noch mal das & vor dem $...
Das sorgt dafür, das keine Kopie angelegt wird, sondern lediglich ein anderer Name verwendet wird.
<?php
foreach (array_keys($allBtns) as $key) /* ... */
?>
Ungünstig, da ein zusätzlicher Aufruf von
array_keys
gemacht werden muss.Stimmt. Ist aber IMHO lesbarar.
<?php
foreach ($allBtns as &$subArr) /* ... */
?>
Da bin ich mir nicht sicher, ob das überhaupt so funktioniert.
Funktioniert: http://www.php.net/manual/de/control-structures.foreach.php
wäre es denn innerhalb einer for-schleife anders?
Deine
for
-Schleife würde meistens auch funktionieren.foreach
ist aber praktischer, da du nicht darauf angewiesen bist, das die Elemente von 0 bis n durchnummeriert sind. Du könntest mit derfor
-Schleife z.B. nicht den Rückgabewert vonhook_menu
durchlaufen.--
---edit---
bitte auf korrekte Verschachtelung von
quote
achten.usort und verschachtelte Arrays
am 15.09.2009 - 09:16 Uhr
Funktioniert: http://www.php.net/manual/de/control-structures.foreach.php
Ah, stimmt ja. Ok.
Damit wäre die ziemlich einfach Lösung des Problems:
<?php
foreach ($allBtns as &$subArr) {
usort($subArr, "cmp_btnID");
}
// ...
?>
Stefan
--
sei nett zu Deinem Themer
also nur ein & davor? was
am 15.09.2009 - 09:21 Uhr
also nur ein & davor?
was genau besagt das &?
ahaa! Zitat: As of PHP 5,
am 15.09.2009 - 09:25 Uhr
ahaa!
As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value.
au mann, kommt mir irgendwie so vor, als ob ich das schon mal hatte...
danke!