247 votes

Comment aplatir un tableau multidimensionnel?

Est-il possible, en PHP, d'aplatir un tableau (bi / multi) dimensionnel sans utiliser de récursivité ou de références?

Je ne m'intéresse qu'aux valeurs afin que les clés puissent être ignorées, je pense aux lignes suivantes: array_map() et array_values() .

285voto

too much php Points 27983

Depuis PHP 5.3, la solution la plus courte semble être array_walk_recursive() avec la nouvelle syntaxe de fermeture:

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

269voto

VolkerK Points 54118

Vous pouvez utiliser la bibliothèque PHP standard (SPL) pour "masquer" la récursivité.

 $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, " ";
}
 

estampes

 1 2 3 4 5 6 7 8 9
 

89voto

Prasanth Bendra Points 9618

Solution pour tableau bidimensionnel

Veuillez essayer ceci:

 $array  = your array

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

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

EDIT: 21 août 13

Voici la solution qui fonctionne pour un tableau multidimensionnel:

 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);
 

Réf: http://php.net/manual/en/function.call-user-func-array.php

24voto

hakre Points 102271

Pour aplatir w/o la récursivité (comme vous l'avez demandé), vous pouvez utiliser une pile. Naturellement, vous pouvez mettre ceci en fonction de ses propres array_flatten. Ce qui suit est une version qui fonctionne w/o touches:.

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
        {
            $stack = array_merge(array_values($value), $stack);
        }
        else // a value to take
        {
           $flat[] = $value;
        }
    }
    return $flat;
}

Les éléments sont traités dans leur ordre. Parce que les sous-éléments, sera déplacé sur le dessus de la pile, elles seront traitées suivant.

Il est possible de faire des clés en compte, cependant, vous aurez besoin d'une stratégie différente pour gérer la pile. C'est nécessaire parce que vous avez besoin pour faire face à d'éventuelles doubles de clés dans le sous-tableaux. Une semblable réponse à une question connexe: PHP Promenade à travers tableau multidimensionnel, tout en préservant les touches

Je ne suis pas spécialement sûr, mais je j'avais testé cela dans le passé: L' RecurisiveIterator n'utiliser la récursivité, donc, cela dépend de ce que vous avez vraiment besoin. Devrait être possible de créer un circuit d'itérateur basé sur des piles ainsi:

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

Démo

Je n'ai pas fait jusqu'à présent, à mettre en œuvre de la pile en fonction RecursiveIterator , ce qui je pense est une bonne idée.

18voto

nilamo Points 1341

Utilise la récursivité. J'espère qu'en voyant à quel point ce n'est pas complexe, votre peur de la récursivité se dissipera une fois que vous verrez comme ce n'est pas complexe.

 function flatten($array) {
    if (!is_array($array)) {
        // nothing to do if it's not an array
        return array($array);
    }

    $result = array();
    foreach ($array as $value) {
        // explode the sub-array, and add the parts
        $result = array_merge($result, flatten($value));
    }

    return $result;
}


$arr = array('foo', array('nobody', 'expects', array('another', 'level'), 'the', 'Spanish', 'Inquisition'), 'bar');
echo '<ul>';
foreach (flatten($arr) as $value) {
    echo '<li>', $value, '</li>';
}
echo '<ul>';
 

Sortie:

 <ul><li>foo</li><li>nobody</li><li>expects</li><li>another</li><li>level</li><li>the</li><li>Spanish</li><li>Inquisition</li><li>bar</li><ul>
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X