Gruppieren Sie Zeilen in einem assoziativen Array von assoziativen Arrays nach Spaltenwert und bewahren Sie die ursprünglichen Schlüssel der ersten Ebene
Lesezeit: 7 Minuten
Anson Kao
Ich habe ein Array von Subarrays im folgenden Format:
Und ich möchte es basierend auf dem ID-Feld in jedem Subarray in ein neues Array gruppieren.
array
(
10 => array
(
e => array ( id = 10, name = bananas )
)
20 => array
(
a => array ( id = 20, name = chimpanzee )
c => array ( id = 20, name = dynasty )
)
40 => array
(
b => array ( id = 40, name = meeting )
)
50 => array
(
d => array ( id = 50, name = chocolate )
f => array ( id = 50, name = fantasy )
g => array ( id = 50, name = football )
)
)
@Herbert, ich vermute, das Schreiben an eine nicht vorhandene ID wirkt sich auf die Leistung aus? oder löst es PHP-Warnungen aus?
– Anson Kao
27. September 2011 um 20:10 Uhr
@SampleJACK: Mein Fehler. Auf den ersten Blick dachte ich, er würde überprüfen, ob eine ID in existiert $old_arr. Jetzt, wo ich es genauer untersuche, benutze array_key_exists fügt diesem Code nichts hinzu. Das Ergebnis ist ohne sie genau das gleiche. In Bezug auf die Leistung: Es ruft eine Funktion in einem Array innerhalb einer Schleife auf, die jeden Leistungseinbruch überwiegen muss, den Sie durch das Schreiben auf einen nicht vorhandenen Schlüssel erleiden würden, daher würde ich vorschlagen, das Ganze fallen zu lassen if() Block.
– Herbert
27. September 2011 um 20:30 Uhr
@Herbert: Ich hatte es hinzugefügt, da ich dachte, dass ein Fehler angezeigt wird, wenn der Schwellenwert für die Fehlerberichterstattung zu niedrig ist. Ich habe es getestet und scheint nicht zu meckern.
– Tim Cooper
27. September 2011 um 20:39 Uhr
@Tim: Ja, ich habe meine Fehlerberichterstattung aufgedreht, um sie anzuzeigen alles und Sie haben Recht – keine Beschwerden. Ich wollte nicht unterstellen, dass es sich in irgendeiner Weise um schlechten Code handelt. SampleJACK hat die Leistung erhöht, und nachdem man darüber nachgedacht hat, ist es sinnvoll, sie fallen zu lassen. Ehrlich gesagt dachte ich, es würde die IDs auf den inneren Arrays überprüfen. Das wird mich lehren, sorgfältiger zu lesen. :p Du bekommst immer noch meine +1 für guten Code.
– Herbert
27. September 2011 um 20:50 Uhr
Ich habe eine Antwort für die Nachwelt hinzugefügt, um zu verdeutlichen, worüber ich gesprochen habe.
– Herbert
27. September 2011 um 20:51 Uhr
foreach($array as $key => $value){
$newarray[$value['id']][$key] = $value;
}
var_dump($newarray);
Stück Kuchen 😉
Wahrscheinlich ist es genauso einfach zu erklären, wie Ihr Code funktioniert und warum Sie der Meinung sind, dass dies die beste Technik ist.
– mickmackusa
17. Juni 2020 um 8:14 Uhr
Aber wirklich, es hat keinen neuen Wert, diese Antwort auf der Seite zu behalten. Diese Nur-Code-Antwort (ein exaktes Duplikat von Tims Technik) wurde 10 Minuten nach dem Posten von Tim gepostet.
– mickmackusa
17. Juni 2020 um 23:25 Uhr
Der folgende Code passt den Code von @Tim Cooper zur Minderung an Undefined index: id Fehler für den Fall, dass eines der inneren Arrays keine enthält Ausweis:
Dies ist ein “erfundenes Problem” – nicht in der Frage des OP enthalten. Wahrscheinlich besser, eine andere Frage zu finden, die dieses Problem aufwirft, und sie dort zu posten.
Hier ist eine Funktion, die ein Array als erstes Argument und ein Kriterium (eine Zeichenfolge oder eine Callback-Funktion) als zweites Argument akzeptiert. Die Funktion gibt ein neues Array zurück, das das Array wie gewünscht gruppiert.
/**
* Group items from an array together by some criteria or value.
*
* @param $arr array The array to group items from
* @param $criteria string|callable The key to group by or a function the returns a key to group by.
* @return array
*
*/
function groupBy($arr, $criteria): array
{
return array_reduce($arr, function($accumulator, $item) use ($criteria) {
$key = (is_callable($criteria)) ? $criteria($item) : $item[$criteria];
if (!array_key_exists($key, $accumulator)) {
$accumulator[$key] = [];
}
array_push($accumulator[$key], $item);
return $accumulator;
}, []);
}
Das Übergeben des Rückrufs ist im obigen Beispiel übertrieben, aber die Verwendung des Rückrufs findet seine Verwendung, wenn Sie ein Array von Objekten, ein mehrdimensionales Array oder etwas Willkürliches übergeben, nach dem Sie gruppieren möchten.
Said Pooyanfar
Vielleicht ist es erwähnenswert, dass Sie auch PHP verwenden können array_reduce Funktion
Aufgrund der Art und Weise, wie der Sortieralgorithmus von PHP mehrdimensionale Arrays behandelt – er sortiert nach Größe und vergleicht dann die Elemente einzeln, können Sie tatsächlich eine schlüsselerhaltende Sortierung für die Eingabe verwenden, BEVOR Sie sie umstrukturieren. Bei der funktionalen Programmierung bedeutet dies, dass Sie das Ergebnisarray nicht als Variable deklarieren müssen.
Ich muss sagen, dass die funktionale Programmierung für diese Aufgabe nicht sehr attraktiv ist, da die Schlüssel der ersten Ebene erhalten bleiben müssen.
Obwohl array_walk() prägnanter ist, erfordert es immer noch, dass das Ergebnisarray als Referenzvariable an die Closure übergeben wird. (Demo)
Ich würde wahrscheinlich eine klassische Schleife für diese Aufgabe empfehlen. Das Einzige, was die Schleife tun muss, ist, die Tasten der ersten und zweiten Ebene neu anzuordnen. (Demo)
Ehrlich gesagt erwarte ich das ksort() wird effizienter sein als Pre-Loop-Sortierung, aber ich wollte eine praktikable Alternative.
14450900cookie-checkGruppieren Sie Zeilen in einem assoziativen Array von assoziativen Arrays nach Spaltenwert und bewahren Sie die ursprünglichen Schlüssel der ersten Ebeneyes