Edit: Das ist keine Hausaufgabe. Ich möchte nur sehen, ob irgendwelche SOers eine kreativere Lösung als die offensichtlichste Route haben. Aber da sich einige Leute darüber beschwert haben, dass dieses Problem zu einfach ist, wie wäre es mit einer allgemeineren Lösung, die mit einem n funktioniertth Dimensions-Array?
?(ps. Ich glaube nicht, dass 12 verschachtelt sind for loops ist in diesem Fall die beste Lösung.)
@Calvin Ich weiß, es ist viele Jahre her (11!), Aber … hast du eine Antwort akzeptiert oder nicht? Ist Ihnen aufgefallen, dass die beliebteste Antwort im Grunde falsch ist, weil einzelne Zeilen nicht unterstützt werden [[1,2,…N]]? Schauen Sie sich die Sandbox für die Illustration an: sandbox.onlinephpfunctions.com/code/…
– Onkeltem
3. Februar 2020 um 1:22 Uhr
Außerdem kann der Splat-Operator keine Zeichenfolgenschlüssel entpacken. Beweis des Fehlers: 3v4l.org/1WSQH …hoppla, mir ist gerade aufgefallen, dass ich das vor über einem Jahr als Antwort auf dieser Seite gesagt habe!
– mickmackusa
23. Juni 2020 um 13:20 Uhr
Kodler
function transpose($array) {
array_unshift($array, null);
return call_user_func_array('array_map', $array);
}
Oder wenn Sie PHP 5.6 oder höher verwenden:
function transpose($array) {
return array_map(null, ...$array);
}
NULL wird als Parameter an array_unshift übergeben, wodurch am Anfang des Arrays ein Wert hinzugefügt wird. Die erste Zeile fügt also NULL als ersten Wert des Arrays ein. Die nächste Zeile ruft array_map mit allen Einträgen von $array als Parameter auf. Es ist also dasselbe wie das Aufrufen von array_map(NULL, $array[0]$array[1]$array[2], usw usw). In der Dokumentation zu array_map gibt es ein Detail: “Eine interessante Verwendung dieser Funktion besteht darin, ein Array von Arrays zu erstellen, was einfach durch die Verwendung von NULL als Name der Callback-Funktion ausgeführt werden kann.”
– Jeremy Warne
26. April 2012 um 23:56 Uhr
Diese Funktion behält die Indizes nicht, wenn sie vom Typ String sind. Es gibt die transponierte Matrix mit numerischem Index zurück. Die Funktion flipDiagonally funktioniert in diesem Fall einwandfrei. Upvote sowieso für die Einfachheit
– luso
24. August 2012 um 14:45 Uhr
Dies bricht zusammen, wenn es nur eine Zeile gibt, z. B. transponieren ( [[1,2]]) Erwartet: [[1],[2]]Tatsächlich: [1,2]
– Chris
16. März 2015 um 21:13 Uhr
sollte eine Beschreibung in der Antwort sein.
– Awlad Liton
14. Oktober 2015 um 11:24 Uhr
aber warum funktioniert das? Diese Antwort ist für mich völlig undurchsichtig
– daniel
26. November 2015 um 12:21 Uhr
Mit 2 Schlaufen.
function flipDiagonally($arr) {
$out = array();
foreach ($arr as $key => $subarr) {
foreach ($subarr as $subkey => $subvalue) {
$out[$subkey][$key] = $subvalue;
}
}
return $out;
}
Obwohl Codlers Antwort prägnanter ist, denke ich, dass dies eigentlich der bessere Weg ist, weil es so viel klarer ist, was vor sich geht. Wenn sich jemand mit Programmiererfahrung, aber kein PHP-Guru, die beiden Antworten ansehen würde, würde er sofort verstehen, was diese tut, müsste aber das Kleingedruckte der Dokumentation lesen, um der anderen zu folgen. +1
– Hackartist
3. Februar 2012 um 23:05 Uhr
Im Gegenteil, ich habe festgestellt, dass dies mit nicht numerischen Tasten nicht so gut funktioniert. Zum Beispiel $test = array(array('a'=>1, 'b'=>2,'c'=>3), array(4,5,6), array(7,8,9));: Es erstellt ein Einzelelement-Array für jeden Wert mit einem nicht numerischen Schlüssel. Mit angegebenen Zifferntasten (z. B. $test = array(array(4,5,6), array(11=>1, 12=>2, 13=>3), array(7,8,9));), macht es etwas Seltsames. Während von allen Rechten dies sollte Arbeit, ich denke, wir brauchen eine bessere Lösung!
– JohannesK
14. Juli 2014 um 20:01 Uhr
@JohnK [0][1] und [2][1] wird werden [1][0] und [1][2]. Es dreht die Schlüssel um. Ich habe Ihre Beispiele ausprobiert und es funktioniert genau wie beabsichtigt. Ich bin mir nicht sicher, was Sie erwartet haben.
– OIS
4. August 2014 um 13:45 Uhr
Hat jemand die beiden Lösungen profiliert? Wie gut skaliert die Lösung von Codler, wenn count($arr) wirklich hoch ist?
– Donquijote
5. Juli 2016 um 15:17 Uhr
@donquixote Codlers Lösung ist falsch. Schlecht. Es unterstützt keine assoziativen Arrays und schlägt im trivialen Randfall einer einzelnen Zeile/Spalte fehl: [[a,b,…,z]]. Es muss abgewertet werden, um die Menschen nicht zu verwirren.
– Onkeltem
3. Februar 2020 um 1:13 Uhr
Ich denke du meinst das Array transponieren (Spalten werden zu Zeilen, Zeilen werden zu Spalten).
Hier ist eine Funktion, die das für Sie erledigt (Quelle):
function array_transpose($array, $selectKey = false) {
if (!is_array($array)) return false;
$return = array();
foreach($array as $key => $value) {
if (!is_array($value)) return $array;
if ($selectKey) {
if (isset($value[$selectKey])) $return[] = $value[$selectKey];
} else {
foreach ($value as $key2 => $value2) {
$return[$key2][$key] = $value2;
}
}
}
return $return;
}
Transponieren eines N-dimensionalen Arrays:
function transpose($array, &$out, $indices = array())
{
if (is_array($array))
{
foreach ($array as $key => $val)
{
//push onto the stack of indices
$temp = $indices;
$temp[] = $key;
transpose($val, $out, $temp);
}
}
else
{
//go through the stack in reverse - make the new array
$ref = &$out;
foreach (array_reverse($indices) as $idx)
$ref = &$ref[$idx];
$ref = $array;
}
}
$foo[1][2][3][3][3] = 'a';
$foo[4][5][6][5][5] = 'b';
$out = array();
transpose($foo, $out);
echo $out[3][3][3][2][1] . ' ' . $out[5][5][6][5][4];
Wirklich hackish und wahrscheinlich nicht die beste Lösung, aber hey, es funktioniert.
Grundsätzlich durchläuft es das Array rekursiv und sammelt die aktuellen Indizes in einem Array.
Sobald es den referenzierten Wert erreicht hat, nimmt es den “Stapel” von Indizes und kehrt ihn um, indem es ihn in das $out-Array einfügt. (Gibt es eine Möglichkeit, die Verwendung des $temp-Arrays zu vermeiden?)
seltsam
Ich brauchte eine Transponierungsfunktion mit Unterstützung für assoziatives Array:
Die array_unshift Trick funktionierte NOCH nicht array_map…
Also habe ich a codiert array_map_join_array Funktion zum Umgang mit der Zuordnung von Datensatzschlüsseln:
/**
* Similar to array_map() but tries to join values on intern keys.
* @param callable $callback takes 2 args, the intern key and the list of associated values keyed by array (extern) keys.
* @param array $arrays the list of arrays to map keyed by extern keys NB like call_user_func_array()
* @return array
*/
function array_map_join_array(callable $callback, array $arrays)
{
$keys = [];
// try to list all intern keys
array_walk($arrays, function ($array) use (&$keys) {
$keys = array_merge($keys, array_keys($array));
});
$keys = array_unique($keys);
$res = [];
// for each intern key
foreach ($keys as $key) {
$items = [];
// walk through each array
array_walk($arrays, function ($array, $arrKey) use ($key, &$items) {
if (isset($array[$key])) {
// stack/transpose existing value for intern key with the array (extern) key
$items[$arrKey] = $array[$key];
} else {
// or stack a null value with the array (extern) key
$items[$arrKey] = null;
}
});
// call the callback with intern key and all the associated values keyed with array (extern) keys
$res[$key] = call_user_func($callback, $key, $items);
}
return $res;
}
Eine zusätzliche Besonderheit/Überraschung bezüglich der Transponierung mit dieser Technik ist die null Elemente werden generiert, wenn die Subarrays unterschiedliche Größen haben … aber vielleicht nicht dort, wo Sie es erwarten würden.
Beachten Sie die Sorgfalt, die diese Funktion an den Tag legt (vergleichbar mit der Gepäckabfertigung, die Ihr Gepäck aus dem Bauch des Flugzeugs holt). Die IDs der ursprünglichen Subarray-Werte werden nicht beachtet (und es wäre egal, ob 1, 2& 3 wurden x, y& z); Was auch immer vom Förderband kommt, wird in den niedrigsten verfügbaren Schlitz geworfen.
Dieses Verhalten ist konsistent und zuverlässig beim Liefern einer vollständigen Matrix. EIN foreach() Schleifenalternative liefert nicht nativ null Element aus Subarrays unterschiedlicher Größe, und in den meisten Implementierungen hängt seine Fähigkeit, auf alle Subarray-Werte zuzugreifen, von der Länge des ersten Subarrays ab.
Wie oben gezeigt, müssten Sie, wenn Sie sicher sein möchten, dass Sie ALLE Daten aus dem Eingabearray extrahiert haben, eine Additionslogik schreiben, um alle eindeutigen Spalten-IDs an die foreach-Schleife zu liefern.
ps Bevor ich von dieser verkürzten transponierenden Syntax erfuhr, schrieb ich einen hässlicheren, ausführlicheren funktionalen Transposer, der einige Kritik einstecken musste.
José Trindade
Ich wurde mit dem gleichen Problem konfrontiert. Hier ist, was ich herausgefunden habe:
@Calvin Ich weiß, es ist viele Jahre her (11!), Aber … hast du eine Antwort akzeptiert oder nicht? Ist Ihnen aufgefallen, dass die beliebteste Antwort im Grunde falsch ist, weil einzelne Zeilen nicht unterstützt werden [[1,2,…N]]? Schauen Sie sich die Sandbox für die Illustration an: sandbox.onlinephpfunctions.com/code/…
– Onkeltem
3. Februar 2020 um 1:22 Uhr
Außerdem kann der Splat-Operator keine Zeichenfolgenschlüssel entpacken. Beweis des Fehlers: 3v4l.org/1WSQH …hoppla, mir ist gerade aufgefallen, dass ich das vor über einem Jahr als Antwort auf dieser Seite gesagt habe!
– mickmackusa
23. Juni 2020 um 13:20 Uhr