Voici un exemple de tableau: et j'aimerais obtenir un résultat comme celui-ci: p> Comment iraiais-tu aller À propos de l'écriture d'une fonction récursive pour gérer cela? p> p>
7 Réponses :
quelque chose comme ceci:
+1 Ceci est assez proche de ce que je ferais. Étant donné que les touches sont modifiées, aucune fonction intégrée qui le fera pour vous, et vous avez certainement besoin de récursives pour réduire toutes les sous-valeurs qui sont également des tableaux.
bon exemple. J'aime l'idée de passer la matrice de sortie par référence.
@Vdvleon Great Post, merci cela m'a aidé. J'avais besoin de travailler pour un objet, donc je l'ai modifié un peu et ajouté à votre réponse.
Voici une fonction qui vous permet de spécifier un préfixe de niveau supérieur via le deuxième paramètre:
function flatten_array($array, $prefix = null) {
if ($prefix) $prefix .= '_';
$items = array();
foreach ($array as $key => $value) {
if (is_array($value))
$items = array_merge($items, flatten_array($value, $prefix . $key));
else
$items[$prefix . $key] = $value;
}
return $items;
}
/**
* Flatten a multi-dimensional array or a nested object, constructing concatenated keys for
* nested elements.
* @param array or object $array - the array or object to be flattened
* @param array or string $key_path - current parent keys path.
* Pass this parameter as string if you need to set a common prefix for all keys
* @param string $level_separator - keys concatenation glue
* @param array $flat - resulting flattened array (omit this parameter when calling the function)
* @return single-dimensional array with all array keys as concatenated keys of elements'
* paths through the data structure
*/
function flattenArray($array, &$key_path = array(), $level_separator = '.', &$flat = array())
{
if(!is_array($key_path))
{
// sanitize key_path
$key_path = array((string)$key_path);
}
foreach($array as $key => $value)
{
// push current key to path
array_push($key_path, $key);
if(is_array($value) || is_object($value))
{
// next level recursion
$flat = array_merge($flat, flattenArray($value, $key_path, $level_separator, $flat));
}
else
{
// write the value directly
$flat[implode($level_separator, $key_path)] = $value;
}
// remove used key
array_pop($key_path);
}
return $flat;
}
Après quelques itérations, j'ai pu affiner une solution à ce problème qui utilise une approche basée sur la pile pour éviter la récursion, simplifier les choses un peu.
/***
* @name array_flatten
* @author Tom Penzer @tpenzer
* Flattens a multi-tiered array into a single-tiered
* associative array with keys reflective of their
* values' hierarchy.
*
* @param array $array Required - the multi-
* level keyed array to be flattened
* @param string $separator Optional - the string
* used to separate the keys from different levels of
* the hierarchy
*
* @return array a single-level keyed array
***/
function array_flatten($array, $separator = '_') {
$output = array();
while (list($key, $value) = each($array)) {
if (is_array($value)) {
$build = array();
foreach ($value as $s_key => $s_value) {
$build[$key . $separator . $s_key] = $s_value;
}
unset($array[$key]);
$array = $build + $array;
unset($build);
continue;//skip write to $output
}
$output[$key] = $value;
unset($array[$key]);
}
return $output;
}
Je pense que cette "astuce" en utilisant est http_build_query est moins d'une récursion de WyeSeore W / OUT (ou du moins de laisser PHP le faire pour vous)
3 lignes de code si votre str_replace utilise les valeurs codées URL pour [ et] p> dollar flat_array devient: p>
Ceci aplatir la matrice associative multidimensionnelle, acheminez un chiffre sur la clé si sa duplicata. Si cela ne vous dérange pas d'avoir un index de chiffres pour différencier les touches en double au lieu de clés concaténées, cela pourrait être une solution.
<?php
$xml_str = "
<images>
<image>
<position>0</position>
</image>
<image1>
<position>10</position>
</image1>
</images>";
// turn the xml into a multidimentional array
$ob = simplexml_load_string($xml_str);
$json = json_encode($ob);
$my_array = json_decode($json, true);
print_r($my_array);
// flatten it
$result = array();
array_walk_recursive($my_array, function($v, $k) use (&$result){ $i = ""; for (; isset($result[$k."$i"]); $i++); $result[$k."$i"] = $v; });
print_r($result);
?>
Une solution avec uniquement des fonctions PHP * PHP + récursif: sortie: p>