337 Stimmen

Wie kann man ein mehrdimensionales Array reduzieren?

Ist es möglich, in PHP ein (bi-/multi) dimensionales Array ohne Rekursion oder Referenzen zu reduzieren?

Ich interessiere mich nur für die Werte, so dass die Schlüssel ignoriert werden können, ich denke in den Linien der array_map() y array_values() .

344voto

too much php Punkte 85034

Ab dem PHP 5.3 die kürzeste Lösung scheint zu sein array_walk_recursive() mit der neuen Syntax für Verschlüsse:

function flatten(array $array) {
    $return = array();
    array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
    return $return;
}

323voto

VolkerK Punkte 93746

Sie können die 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, " ";
}

druckt

1 2 3 4 5 6 7 8 9

187voto

Joyce Babu Punkte 17895

In PHP 5.6 und höher können Sie zweidimensionale Arrays mit array_merge nach dem Auspacken des äußeren Arrays mit ... Betreiber. Der Code ist einfach und klar.

array_merge(...$a);

Dies funktioniert auch mit Sammlungen von assoziativen Arrays.

$a = [[10, 20], [30, 40]];
$b = [["x" => "X", "y" => "Y"], ["p" => "P", "q" => "Q"]];

print_r(array_merge(...$a));
print_r(array_merge(...$b));

Array
(
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
)
Array
(
    [x] => X
    [y] => Y
    [p] => P
    [q] => Q
)

In PHP 8.0 und darunter funktioniert das Entpacken von Arrays nicht, wenn das äußere Array nicht numerische Schlüssel hat. Unterstützung für Array mit String-Schlüsseln entpacken ist ab PHP 8.1 verfügbar. Um 8.0 und darunter zu unterstützen, sollten Sie array_values Erstens.

$c = ["a" => ["x" => "X", "y" => "Y"], "b" => ["p" => "P", "q" => "Q"]];
print_r(array_merge(...array_values($c)));

Array
(
    [x] => X
    [y] => Y
    [p] => P
    [q] => Q
)

Update: Basierend auf einem Kommentar von @MohamedGharib

Dies führt zu einem Fehler, wenn das äußere Array leer ist, da array_merge würde mit null Argumenten aufgerufen werden. Dies kann durch Hinzufügen eines leeren Arrays als erstes Argument vermieden werden.

array_merge([], ...$a);

98voto

Prasanth Bendra Punkte 28775

Lösung für 2 dimensionales Array

Bitte versuchen Sie dies:

$array  = your array

$result = call_user_func_array('array_merge', $array);

echo "<pre>";
print_r($result);

EDIT : 21-Aug-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

27voto

hakre Punkte 184133

Um ohne Rekursion zu flatten (wie Sie es gewünscht haben), können Sie eine Stapel . Natürlich können Sie dies in eine eigene Funktion einbauen, z. B. array_flatten . Es folgt eine Version, die ohne Schlüssel 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;
}

Die Elemente werden in ihrer Reihenfolge verarbeitet. Da die Unterelemente auf dem Stapel nach oben verschoben werden, werden sie als nächstes verarbeitet.

Es ist möglich, auch Schlüssel zu berücksichtigen, allerdings ist dann eine andere Strategie für den Umgang mit dem Stapel erforderlich. Das ist notwendig, weil Sie mit möglichen doppelten Schlüsseln in den Unterfeldern umgehen müssen. Eine ähnliche Antwort in einer verwandten Frage: PHP Walk durch mehrdimensionales Array unter Beibehaltung der Schlüssel

Ich bin mir nicht ganz sicher, aber ich habe dies in der Vergangenheit getestet: Die RecurisiveIterator verwendet eine Rekursion, es kommt also darauf an, was Sie wirklich brauchen. Es sollte auch möglich sein, einen rekursiven Iterator auf Basis von Stapeln zu erstellen:

foreach(new FlatRecursiveArrayIterator($array) as $key => $value)
{
    echo "** ($key) $value\n";
}

Demo

Ich habe es nicht geschafft, den Stack auf der Basis von RecursiveIterator was ich für eine gute Idee halte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X