
Alix Axel
Ist es in PHP möglich, ein (zwei-/mehr-)dimensionales Array ohne Verwendung von Rekursion oder Referenzen zu glätten?
Ich interessiere mich nur für die Werte, damit die Schlüssel ignoriert werden können, ich denke in den Zeilen von array_map()
und array_values()
.
Du kannst den … benutzen Standard-PHP-Bibliothek (SPL) um die Rekursion zu “verstecken”.
$a = array(1,2,array(3,4, array(5,6,7), 8), 9);
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($a));
foreach($it as $v) {
echo $v, " ";
}
Drucke
1 2 3 4 5 6 7 8 9

Prasanth Bendra
Lösung für zweidimensionales Array
Bitte versuchen Sie Folgendes:
$array = your array
$result = call_user_func_array('array_merge', $array);
echo "<pre>";
print_r($result);
EDIT: 21. August 13
Hier ist die Lösung, die für mehrdimensionale Arrays funktioniert:
function array_flatten($array) {
$return = array();
foreach ($array as $key => $value) {
if (is_array($value)){
$return = array_merge($return, array_flatten($value));
} else {
$return[$key] = $value;
}
}
return $return;
}
$array = Your array
$result = array_flatten($array);
echo "<pre>";
print_r($result);
Ref: http://php.net/manual/en/function.call-user-func-array.php

Walf
Um ohne Rekursion zu glätten (wie Sie es gewünscht haben), können Sie a verwenden Stapel. Natürlich können Sie dies in eine eigene Funktion packen array_flatten
. Das Folgende ist eine Version, die ohne Tasten funktioniert:.
function array_flatten(array $array)
{
$flat = array(); // initialize return array
$stack = array_values($array); // initialize stack
while($stack) // process stack until done
{
$value = array_shift($stack);
if (is_array($value)) // a value to further process
{
array_unshift($stack, ...$value);
}
else // a value to take
{
$flat[] = $value;
}
}
return $flat;
}
Elemente werden in ihrer Reihenfolge verarbeitet. Da Unterelemente auf den Stapel verschoben werden, werden sie als nächstes verarbeitet.
Es ist möglich, auch Schlüssel zu berücksichtigen, aber Sie benötigen eine andere Strategie, um mit dem Stack umzugehen. Dies ist erforderlich, da Sie mit möglichen doppelten Schlüsseln in den Unterarrays umgehen müssen. Eine ähnliche Antwort in einer verwandten Frage: PHP Gehen Sie durch ein mehrdimensionales Array, während Sie Schlüssel beibehalten
Ich bin mir nicht ganz sicher, aber ich hatte das in der Vergangenheit getestet: The RecurisiveIterator
verwendet Rekursion, also hängt es davon ab, was Sie wirklich brauchen. Es sollte möglich sein, auch einen rekursiven Iterator basierend auf Stapeln zu erstellen:
foreach(new FlatRecursiveArrayIterator($array) as $key => $value)
{
echo "** ($key) $value\n";
}
Demo
Ich habe es bisher nicht geschafft, den Stack basierend auf zu implementieren RecursiveIterator
was ich für eine schöne idee halte.
Ich dachte nur, ich würde darauf hinweisen, dass dies eine Faltung ist, sodass array_reduce verwendet werden kann:
array_reduce($my_array, 'array_merge', array());
BEARBEITEN: Beachten Sie, dass dies so zusammengesetzt werden kann, dass eine beliebige Anzahl von Ebenen abgeflacht wird. Wir können dies auf verschiedene Weise tun:
// Reduces one level
$concat = function($x) { return array_reduce($x, 'array_merge', array()); };
// We can compose $concat with itself $n times, then apply it to $x
// This can overflow the stack for large $n
$compose = function($f, $g) {
return function($x) use ($f, $g) { return $f($g($x)); };
};
$identity = function($x) { return $x; };
$flattenA = function($n) use ($compose, $identity, $concat) {
return function($x) use ($compose, $identity, $concat, $n) {
return ($n === 0)? $x
: call_user_func(array_reduce(array_fill(0, $n, $concat),
$compose,
$identity),
$x);
};
};
// We can iteratively apply $concat to $x, $n times
$uncurriedFlip = function($f) {
return function($a, $b) use ($f) {
return $f($b, $a);
};
};
$iterate = function($f) use ($uncurriedFlip) {
return function($n) use ($uncurriedFlip, $f) {
return function($x) use ($uncurriedFlip, $f, $n) {
return ($n === 0)? $x
: array_reduce(array_fill(0, $n, $f),
$uncurriedFlip('call_user_func'),
$x);
}; };
};
$flattenB = $iterate($concat);
// Example usage:
$apply = function($f, $x) {
return $f($x);
};
$curriedFlip = function($f) {
return function($a) use ($f) {
return function($b) use ($f, $a) {
return $f($b, $a);
}; };
};
var_dump(
array_map(
call_user_func($curriedFlip($apply),
array(array(array('A', 'B', 'C'),
array('D')),
array(array(),
array('E')))),
array($flattenA(2), $flattenB(2))));
Natürlich könnten wir auch Schleifen verwenden, aber die Frage fragt nach einer Kombinatorfunktion nach dem Vorbild von array_map oder array_values.
9935800cookie-checkWie flacht man ein mehrdimensionales Array ab?yes
Warum Rekursion vermeiden?
– JorenB
23. August 2009 um 23:53 Uhr
Dupe (meistens) stackoverflow.com/questions/526556/…
– Kletus
23. August 2009 um 23:53 Uhr
Sie können mit allen Elementen eines beliebig tiefen Arrays ohne Rekursion nichts anfangen (Sie können es als Iteration tarnen, aber Potato, Potahto.) Wenn Sie nur vermeiden möchten, den Code für die Rekursionsbehandlung selbst zu schreiben, verwenden Sie dk2.php.net/manual/en/function.array-walk-recursive.php mit einem Callback, der das Element zu einem verfügbaren Array hinzufügt (verwenden Sie global, den Parameter userdata, packen Sie alles in eine Klasse und verweisen Sie auf $this usw.)
– Michael Madson
24. August 2009 um 0:05 Uhr
@JorenB: Ich würde gerne sehen, dass eine Implementierung archiviert werden könnte.
– Alix Axel
24. August 2009 um 1:42 Uhr
Schau mal rein ebnen Funktion ab Nsp. Sie können damit auch eine Tiefe angeben.
– Ihor Burlachenko
24. Februar 2016 um 20:34 Uhr