11
votes

PHP Convertissez une matrice imbriquée en une seule case pendant que des touches de concaténation?

Voici un exemple de tableau: xxx

et j'aimerais obtenir un résultat comme celui-ci: xxx

Comment iraiais-tu aller À propos de l'écriture d'une fonction récursive pour gérer cela?


0 commentaires

7 Réponses :


16
votes

quelque chose comme ceci: xxx


3 commentaires

+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.



3
votes

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


0 commentaires

0
votes
/**
 * 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;
  }

0 commentaires

0
votes

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


0 commentaires

8
votes

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] xxx

dollar flat_array devient: xxx


0 commentaires

0
votes

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


0 commentaires

1
votes

Une solution avec uniquement des fonctions PHP * PHP + récursif: xxx

sortie: xxx


0 commentaires