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 pour que les touches puissent être ignorées, je pense dans les lignes de array_map()
et array_values()
.
php
arrays
multidimensional-array
flatten
Alix Axel
la source
la source
Réponses:
Vous pouvez utiliser la bibliothèque PHP standard (SPL) pour "masquer" la récursivité.
impressions
la source
iterator_to_array($it, false)
évite le besoin de foreach.function flatten($arr){ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); return iterator_to_array($it, true); }
j'espère que cela aide les autres.Depuis PHP 5.3, la solution la plus courte semble être
array_walk_recursive()
avec la nouvelle syntaxe de fermeture:la source
use
syntaxe pour faire fonctionner celaarray_walk_recursive
car il n'acceptera pas le$userdata
paramètre facultatif par référenceSolution pour tableau bidimensionnel
Veuillez essayer ceci:
EDIT: 21 août 13
Voici la solution qui fonctionne pour les tableaux multidimensionnels:
Réf: http://php.net/manual/en/function.call-user-func-array.php
la source
call_user_func_array('array_merge', [])
(remarquez le tableau vide) renvoie null et déclenche une erreur d'avertissement php. C'est une solution astucieuse si vous savez pertinemment que votre tableau ne sera pas vide, mais ce n'est pas une hypothèse commune que beaucoup peuvent faire.$result = $array ?call_user_func_array('array_merge', $array) : [];
En PHP 5.6 et supérieur, vous pouvez aplatir les tableaux bidimensionnels
array_merge
après avoir déballé le tableau extérieur avec l'...
opérateur. Le code est simple et clair.Cela fonctionne également avec la collection de tableaux associatifs.
Mais cela ne fonctionne pas lorsque le tableau externe a des clés non numériques. Dans ce cas, vous devrez d'
array_values
abord appeler .Mise à jour: basé sur le commentaire de @MohamedGharib
Cela générera une erreur si le tableau externe est vide, car
array_merge
serait appelé avec zéro argument. Il peut être évité en ajoutant un tableau vide comme premier argument.la source
array_merge([], ...$a);
Pour aplatir sans récursivité (comme vous l'avez demandé), vous pouvez utiliser une pile . Naturellement, vous pouvez mettre cela dans une fonction qui lui est propre
array_flatten
. Ce qui suit est une version qui fonctionne sans touches:.Les éléments sont traités dans leur ordre. Étant donné que les sous-éléments seront déplacés au-dessus de la pile, ils seront traités ensuite.
Il est également possible de prendre en compte les clés, mais vous aurez besoin d'une stratégie différente pour gérer la pile. Cela est nécessaire car vous devez gérer les éventuelles clés en double dans les sous-tableaux. Une réponse similaire dans une question connexe: PHP Parcourez un tableau multidimensionnel tout en préservant les clés
Je ne suis pas particulièrement sûr, mais je l'ai déjà testé dans le passé: le
RecurisiveIterator
utilise la récursivité, donc cela dépend de ce dont vous avez vraiment besoin. Il devrait également être possible de créer un itérateur récursif basé sur des piles:Démo
Je n'ai pas réussi jusqu'ici à implémenter la pile sur
RecursiveIterator
laquelle je pense que c'est une bonne idée.la source
if(!empty($value)){$flat[] = $value}
à l'intérieur de l'instruction else pour empêcher l'ajout de vide au tableau de résultats. Fonction géniale!Réponse simple et à une ligne .
Usage:
Sortie (en PsySH):
Maintenant, c'est à vous de voir comment vous allez gérer les clés. À votre santé
EDIT (01/03/2017)
Citant la préoccupation / le problème de Nigel Alderton :
Citant la réponse de Svish :
la source
$array = ['a',['b','c']]
devientArray ([0] => b, [1] => c )
. Le'a'
est perdu car'b'
possède également une clé de0
.false
comme deuxième paramètre ($use_keys
) à l'iterator_to_array
appel.Utilise la récursivité. Avec un peu de chance, en voyant à quel point c'est non complexe, votre peur de la récursivité se dissipera une fois que vous verrez à quel point ce n'est pas complexe.
Production:
la source
Je pensais juste souligner que c'est un pli, donc array_reduce peut être utilisé:
EDIT: Notez que cela peut être composé pour aplatir n'importe quel nombre de niveaux. Nous pouvons le faire de plusieurs manières:
Bien sûr, nous pourrions également utiliser des boucles, mais la question demande une fonction de combinaison le long des lignes de array_map ou array_values.
la source
fold
faire en 4 niveaux, oufold . fold
obtenir 3 niveaux, oufold . fold . fold
obtenir 2 niveaux, etc. Cela empêche également les bogues de se cacher; par exemple. si je veux aplatir un tableau 5D mais que je reçois un tableau 4D, l'erreur se déclenchera immédiatement.$concat
, je pense que vous devriez simplement l'appeler$flatten
.array_merge
est l'équivalent php de concat. J'ai essayé d'êtrearray_concat
ajouté comme alias pourarray_merge
.Aplatit uniquement les tableaux bidimensionnels:
la source
Cette solution est non récursive. Notez que l'ordre des éléments sera quelque peu mélangé.
la source
shifting
la valeur du tableau et son ajout à la fin n'a pas beaucoup de sens. Je suppose que tu le voulais à laarray_merge()
place?Je crois que c'est la solution la plus propre sans utiliser de mutations ni de classes inconnues.
la source
Essayez la fonction simple suivante:
Donc à partir de là:
vous obtenez:
la source
L'astuce consiste à passer les tableaux source et destination par référence.
la source
Extrait de Gist
la source
Vous pouvez le faire avec des goodies ouzo :
Voir: ici
la source
Si vous n'aimez vraiment pas une récursivité ... essayez plutôt de changer :)
Remarque: dans cette version simple, cela ne prend pas en charge les clés de tableau.
la source
continue
, c'est un peu plus rapide.Que diriez-vous d'utiliser un générateur récursif? https://ideone.com/d0TXCg
la source
Pour php 5.2
la source
Cette version peut faire des niveaux profonds, peu profonds ou un nombre spécifique de niveaux:
la source
Parce que le code ici semble effrayant. Voici une fonction qui convertira également un tableau multidimensionnel en syntaxe compatible avec le format html, mais qui est plus facile à lire.
la source
Ceci peut être réalisé en utilisant
array_walk_recursive
Exemple de travail: - https://3v4l.org/FpIrG
la source
Voici ma solution, en utilisant une référence:
la source
la source
Voici une approche simpliste:
la source
Quiconque cherche une solution vraiment propre à cela; voici une option:
Impressions
la source
Je poste juste une autre solution)
la source
Si vous souhaitez également conserver vos clés, c'est la solution.
Malheureusement, il ne produit que des tableaux imbriqués finaux, sans touches centrales. Donc pour l'exemple suivant:
La sortie est:
la source
J'avais besoin de représenter un tableau multidimensionnel PHP au format d'entrée HTML.
la source
$var['a']['b']['c'][0] = 'a'; ...
.Si vous avez un tableau d'objets et que vous souhaitez l'aplatir avec un nœud, utilisez simplement cette fonction:
la source