How to convert all keys in a multi-dimenional array to snake_case?

前端 未结 7 2382
無奈伤痛
無奈伤痛 2021-02-14 09:08

I am trying to convert the keys of a multi-dimensional array from CamelCase to snake_case, with the added complication that some keys have an exclamation mark that I\'d like rem

相关标签:
7条回答
  • 2021-02-14 09:20

    You can run a foreach on the arrays keys, this way you'll rename the keys in-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 讨论(0)
  • 2021-02-14 09:34

    Although this may not be an exact answer to the question, but I wanted to post it here for people who are searching for elegant solution for changing key case in multidimensional PHP arrays. You can also adapt it for changing array keys in general. Just call a different function instead of 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));
    }
    
    0 讨论(0)
  • 2021-02-14 09:40

    Create a function like:

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

    and call this like:

    $newArray = convertToCamelCase($array);
    

    for working example see this

    0 讨论(0)
  • 2021-02-14 09:40
    <?php
    
    class Maison {
        
        public $superficieAll_1;
        public $addressBook;
        
    }
    
    class Address { 
        public $latitudeAmi;
        public $longitude;
    }
    
    $maison = new Maison();
    $maison->superficieAll_1 = 80;
    $maison->addressBook->longitudeAmi = 2;
    $maison->addressBook->latitude = 4;
    
    $returnedArray = transformation($maison);
    print_r($returnedArray);
    
    function transformation($obj){
        //object to array
        $array = json_decode(json_encode((array) $obj),true);
        //now transform all array keys
        return transformKeys($array);
    }    
    
    function transformKeys($array)
    {
        foreach ($array as $key => $value){
            // echo "$key <br>";
            unset($array[$key]);
            $transformedKey = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', ltrim($key, '!')));
            $array[$transformedKey] = $value;  
            // echo "$transformedKey update <br>";
            if (is_array($value)) {
                $array[$transformedKey] = transformKeys($value);
            }
        }
        return $array;
    }
    
    0 讨论(0)
  • 2021-02-14 09:41

    This is the modified function I have used, taken from soulmerge's response:

    function transformKeys(&$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 = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', ltrim($key, '!')));
        # Work recursively
        if (is_array($value)) transformKeys($value);
        # Store with new key
        $array[$transformedKey] = $value;      
        # Do not forget to unset references!
        unset($value);
      endforeach;
    }
    
    0 讨论(0)
  • 2021-02-14 09:43

    Here's a more generalized version of Aaron's. This way you can just plug the function you want to be operated on for all keys. I assumed a static class.

    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 讨论(0)
提交回复
热议问题