2009-09-18 7 views
4

J'essaye de convertir les clefs d'un tableau multidimensionnel de CamelCase en snake_case, avec la complication supplémentaire que certaines clefs ont un point d'exclamation que je voudrais enlever.Comment convertir toutes les clés d'une matrice multidimensionnelle en snake_case?

Par exemple:

$array = array(
    '!AccountNumber' => '00000000', 
    'Address' => array(
    '!Line1' => '10 High Street', 
    '!line2' => 'London')); 

Je voudrais convertir:

$array = array(
    'account_number' => '00000000', 
    'address' => array(
    'line1' => '10 High Street', 
    'line2' => 'London')); 

Mon tableau de la vie réelle est énorme et va profondément de nombreux niveaux. Toute aide sur la façon d'aborder cela est très appréciée!

+0

'cas de serpent' ressemble à 'minuscules' me . Tu apprends quelque chose de nouveau tous les jours. – pavium

+0

Utilisez foreach() dans une fonction récursive! – Artelius

+0

OK, je vois la différence maintenant - snake_case a des underscores à la place des espaces. – pavium

Répondre

7

Ceci est la fonction modifiée que je l'ai utilisé, tiré de la réponse soulmerge:

0

Je dirais que vous auriez à écrire une fonction pour copier le tableau (un niveau) et que cette fonction s'appelle lui-même si l'une des valeurs est un tableau (une fonction récursive).

  • Les points d'exclamation sont facilement enlevés à l'aide de garniture()
  • Le trait de soulignement avant que les caractères majuscules au milieu peut être ajouté à l'aide d'une expression rationnelle
  • Après avoir ajouté le trait de soulignement, la clé entière peut être convertie en baisse case

Sur quoi exactement avez-vous besoin d'aide?

1

Vous pouvez exécuter un foreach sur les touches de tableaux, de cette façon vous renommer les clés en place:

function transformKeys(&$array) { 
    foreach (array_keys($array) as $key) { 
     # This is what you actually want to do with your keys: 
     # - remove exclamation marks at the front 
     # - camelCase to snake_case 
     $transformedKey = ltrim($key, '!'); 
     $transformedKey = strtolower($transformedKey[0] . preg_replace('/[A-Z]/', '_$0', substr($transformedKey, 1))); 
     # Store with new key 
     $array[$transformedKey] = &$array[$key]; 
     unset($array[$key]); 
     # Work recursively 
     if (is_array($array[$transformedKey])) { 
      transformKeys($array[$transformedKey]); 
     } 
    } 
} 
+0

Merci pour cela, ça m'a mis dans la bonne direction mais il y avait quelques problèmes. Tout d'abord, le $ transforméKey crachait des résultats bizarres, j'ai donc légèrement modifié cette ligne.De même, l'instruction récursive if doit être positionnée au-dessus de la ligne stockant la nouvelle clé de tableau pour une raison quelconque. Je posterai ma fonction modifiée ci-dessous. – aaronrussell

+0

Juste remarqué, devrait être réparé maintenant. – soulmerge

2

Bien que ce ne soit peut-être pas une réponse exacte à la question, mais je voulais l'afficher ici pour les personnes qui recherchent une solution élégante pour changer le cas clé dans les tableaux PHP multidimensionnels. Vous pouvez également l'adapter pour changer les clés de tableau en général. Il suffit d'appeler une autre fonction au lieu de array_change_key_case_recursive

// converts all keys in a multidimensional array to lower or upper case 
function array_change_key_case_recursive($arr, $case=CASE_LOWER) 
{ 
    return array_map(function($item)use($case){ 
    if(is_array($item)) 
     $item = array_change_key_case_recursive($item, $case); 
    return $item; 
    },array_change_key_case($arr, $case)); 
} 
1

Voici une version plus généralisée de Aaron. De cette façon, vous pouvez simplement brancher la fonction que vous voulez utiliser pour toutes les touches. J'ai supposé une classe statique.

public static function toCamelCase ($string) { 
    $string_ = str_replace(' ', '', ucwords(str_replace('_',' ', $string))); 
    return lcfirst($string_); 
} 

public static function toUnderscore ($string) { 
    return strtolower(preg_replace('/([^A-Z])([A-Z])/', "$1_$2", $string)); 
} 

// http://stackoverflow.com/a/1444929/632495 
function transformKeys($transform, &$array) { 
    foreach (array_keys($array) as $key): 
    # Working with references here to avoid copying the value, 
    # since you said your data is quite large. 
    $value = &$array[$key]; 
    unset($array[$key]); 
    # This is what you actually want to do with your keys: 
    # - remove exclamation marks at the front 
    # - camelCase to snake_case 
    $transformedKey = call_user_func($transform, $key); 
    # Work recursively 
    if (is_array($value)) self::transformKeys($transform, $value); 
    # Store with new key 
    $array[$transformedKey] = $value; 
    # Do not forget to unset references! 
    unset($value); 
    endforeach; 
} 

public static function keysToCamelCase ($array) { 
    self::transformKeys(['self', 'toCamelCase'], $array); 
    return $array; 
} 

public static function keysToUnderscore ($array) { 
    self::transformKeys(['self', 'toUnderscore'], $array); 
    return $array; 
} 
0

Créer une fonction comme:

function convertToCamelCase($array){ 

      $finalArray  =  array(); 

      foreach ($array as $key=>$value): 

        if(strpos($key, "_")) 
          $key     =  lcfirst(str_replace("_", "", ucwords($key, "_"))); //let's convert key into camelCase 


        if(!is_array($value)) 
          $finalArray[$key]  =  $value; 
        else 
          $finalArray[$key]  =  $this->_convertToCamelCase($value); 
      endforeach; 

      return $finalArray; 
} 

et appeler cela comme:

$newArray = convertToCamelCase($array); 

par exemple travailler see this

Questions connexes