C'est probablement une question de débutant, mais je consulte déjà la documentation depuis plus longtemps et je ne trouve aucune solution. Je pensais pouvoir utiliser implode pour chaque dimension, puis rassembler ces chaînes avec str_split
pour créer un nouveau tableau simple. Cependant, je ne sais jamais si le modèle de jointure n'est pas aussi dans les valeurs et donc, après avoir utilisé str_split
, mes valeurs d'origine pourraient se briser.
Existe-t-il quelque chose comme combine($array1, $array2)
pour les tableaux dans un tableau multidimensionnel?
<?php
$aNonFlat = array(
1,
2,
array(
3,
4,
5,
array(
6,
7
),
8,
9,
),
10,
11
);
$objTmp = (object) array('aFlat' => array());
array_walk_recursive($aNonFlat, create_function('&$v, $k, &$t', '$t->aFlat[] = $v;'), $objTmp);
var_dump($objTmp->aFlat);
/*
array(11) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
[9]=>
int(10)
[10]=>
int(11)
}
*/
?>
Testé avec PHP 5.5.9-1ubuntu4.24 (cli) (construit le 16 mars 2018 à 12:32:06)
$array = your array
$result = call_user_func_array('array_merge', $array);
echo "<pre>";
print_r($result);
REF: http://php.net/manual/en/function.call-user-func-array.php
Voici une autre solution (fonctionne avec un tableau multi-dimensionnel):
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);
Ceci est une ligne, SUPER facile à utiliser:
$result = array();
array_walk_recursive($original_array,function($v) use (&$result){ $result[] = $v; });
Il est très facile à comprendre, à l’intérieur de la fonction/fermeture anonyme. $v
est la valeur de votre $original_array
.
// $array = your multidimensional array
$flat_array = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $k=>$v){
$flat_array[$k] = $v;
}
Également documenté: http://www.phpro.org/examples/Flatten-Array.html
function flatten_array($array, $preserve_keys = 0, &$out = array()) {
# Flatten a multidimensional array to one dimension, optionally preserving keys.
#
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
foreach($array as $key => $child)
if(is_array($child))
$out = flatten_array($child, $preserve_keys, $out);
elseif($preserve_keys + is_string($key) > 1)
$out[$key] = $child;
else
$out[] = $child;
return $out;
}
Une autre méthode de PHP commentaires utilisateur (simplifié) et ici :
function array_flatten_recursive($array) {
if (!$array) return false;
$flat = array();
$RII = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($RII as $value) $flat[] = $value;
return $flat;
}
Le gros avantage de cette méthode est qu’elle suit la profondeur de la récursion, si vous en avez besoin tout en étant aplatie.
Cela produira:
$array = array(
'A' => array('B' => array( 1, 2, 3)),
'C' => array(4, 5)
);
print_r(array_flatten_recursive($array));
#Returns:
Array (
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Avec PHP 7, vous pouvez utiliser des générateurs et leur délégation (yield from
) pour aplatir un tableau:
function array_flatten_iterator (array $array) {
foreach ($array as $value) {
if (is_array($value)) {
yield from array_flatten_iterator($value);
} else {
yield $value;
}
}
}
function array_flatten (array $array) {
return iterator_to_array(array_flatten_iterator($array), false);
}
Exemple:
$array = [
1,
2,
[
3,
4,
5,
[
6,
7
],
8,
9,
],
10,
11,
];
var_dump(array_flatten($array));
En PHP> = 5.3 et basé sur la réponse de Luc M (le premier), vous pouvez utiliser des fermetures comme celle-ci
array_walk_recursive($aNonFlat, function(&$v, $k, &$t){$t->aFlat[] = $v;}, $objTmp);
J'aime cela car je n'ai pas à entourer le code de la fonction avec des guillemets, comme lors de l'utilisation de create_function ()
Une solution non récursive (mais destructrice d'ordre):
function flatten($ar) {
$toflat = array($ar);
$res = array();
while (($r = array_shift($toflat)) !== NULL) {
foreach ($r as $v) {
if (is_array($v)) {
$toflat[] = $v;
} else {
$res[] = $v;
}
}
}
return $res;
}
Si vous avez spécifiquement un tableau de tableaux qui ne va pas plus loin qu'un niveau (un cas d'utilisation que je trouve commun), vous pouvez vous en sortir avec array_merge
et l'opérateur Splat.
<?php
$notFlat = [[1,2],[3,4]];
$flat = array_merge(...$notFlat);
var_dump($flat);
Sortie:
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
L'opérateur Splat modifie efficacement le tableau de tableaux en une liste de tableaux comme arguments pour array_merge
.
Utilisation de fonctions d’ordre supérieur (note: j’utilise des fonctions anonymes inline , apparues dans PHP 5.3):
function array_flatten($array) {
return array_reduce(
$array,
function($prev, $element) {
if (!is_array($element))
$prev[] = $element;
else
$prev = array_merge($prev, array_flatten($element));
return $prev;
},
array()
);
}
Si vous acceptez de perdre des clés de tableau, vous pouvez aplatir un tableau multidimensionnel en utilisant une fermeture récursive en tant que rappel utilisant array_values (), en vous assurant que ce rappel est un paramètre pour array_walk (), comme suit.
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = null;
$callback = function ( $item ) use(&$callback, &$nu_array) {
if (!is_array($item)) {
$nu_array[] = $item;
}
else
if ( is_array( $item ) ) {
foreach( array_values($item) as $v) {
if ( !(is_array($v))) {
$nu_array[] = $v;
}
else
{
$callback( $v );
continue;
}
}
}
};
array_walk($array, $callback);
print_r($nu_array);
L'inconvénient de l'exemple précédent est qu'il implique l'écriture de beaucoup plus de code que la solution suivante qui utilise array_walk_recursive () avec un rappel simplifié:
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = [];
array_walk_recursive($array, function ( $item ) use(&$nu_array )
{
$nu_array[] = $item;
}
);
print_r($nu_array);
Voir code live
Cet exemple semble préférable au précédent, masquant les détails sur la façon dont les valeurs sont extraites d'un tableau multidimensionnel. Bien sûr, l'itération se produit, mais que cela implique une ou plusieurs structures de contrôle, vous ne le saurez qu'en parcourant array.c. Étant donné que la programmation fonctionnelle met l’accent sur les entrées et les sorties plutôt que sur l’obtention d’un résultat, on peut certainement rester indifférent à la manière dont se déroule l’itération en coulisse, c’est-à-dire jusqu’à ce que l’employeur potentiel pose une telle question.
/*consider $mArray as multidimensional array and $sArray as single dimensional array
this code will ignore the parent array
*/
function flatten_array2($mArray) {
$sArray = array();
foreach ($mArray as $row) {
if ( !(is_array($row)) ) {
if($sArray[] = $row){
}
} else {
$sArray = array_merge($sArray,flatten_array2($row));
}
}
return $sArray;
}
Une nouvelle approche basée sur l'exemple de fonction précédent soumis par chaos, qui corrige le bogue de réécriture des clés de chaîne dans plusieurs tableaux:
# Flatten a multidimensional array to one dimension, optionally preserving keys.
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
function flatten_array($array, $preserve_keys = 2, &$out = array(), &$last_subarray_found)
{
foreach($array as $key => $child)
{
if(is_array($child))
{
$last_subarray_found = $key;
$out = flatten_array($child, $preserve_keys, $out, $last_subarray_found);
}
elseif($preserve_keys + is_string($key) > 1)
{
if ($last_subarray_found)
{
$sfinal_key_value = $last_subarray_found . "_" . $key;
}
else
{
$sfinal_key_value = $key;
}
$out[$sfinal_key_value] = $child;
}
else
{
$out[] = $child;
}
}
return $out;
}
Example:
$newarraytest = array();
$last_subarray_found = "";
$this->flatten_array($array, 2, $newarraytest, $last_subarray_found);
vous pouvez essayer ceci:
function flat_an_array($a)
{
foreach($a as $i)
{
if(is_array($i))
{
if($na) $na = array_merge($na,flat_an_array($i));
else $na = flat_an_array($i);
}
else $na[] = $i;
}
return $na;
}
J'ai trouvé un moyen simple de convertir un tableau à plusieurs niveaux en un . J'utilise la fonction "http_build_query" qui convertit le tableau en une chaîne d'URL . Ensuite, divisez la chaîne avec exploser et décoder la valeur.
Voici un échantillon.
$converted = http_build_query($data);
$rows = explode('&', $converted);
$output = array();
foreach($rows AS $k => $v){
list($kk, $vv) = explode('=', $v);
$output[ urldecode($kk) ] = urldecode($vv);
}
return $output;
Approche simple..Voir via récursivité ..
<?php
function flatten_array($simple){
static $outputs=array();
foreach ( $simple as $value)
{
if(is_array($value)){
flatten_array($value);
}
else{
$outputs[]=$value;
}
}
return $outputs;
}
$eg=['s'=>['p','n'=>['t']]];
$out=flatten_array($eg);
print_r($out);
?>
Vous pouvez utiliser la fonction flatten from from Bibliothèque PHP non standard (NSPL) . Cela fonctionne avec les tableaux et toutes les structures de données itérables.
assert([1, 2, 3, 4, 5, 6, 7, 8, 9] === flatten([[1, [2, [3]]], [[[4, 5, 6]]], 7, 8, [9]]));