1

I got an array and would like to convert its array keys from camel case to underscore case. How this could be done?

$before = ['ThisIsATest' => 'Something', 'cheeseCake' => 'Something else'];
$after = ['this_is_a_test' => 'Something', 'cheese_cake' => 'Something else'];

I primarily would like to know how to update array keys!


Based on your input i created the following two functions:

function camelToUnderscore($string)
{
    if (is_numeric($string)) {
        return $string;
    }

    preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $string, $matches);
    $ret = $matches[0];
    foreach ($ret as &$match) {
        $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
    }

    return implode('_', $ret);
}

function keysCamelToUnderscore(array $array)
{
    $newArray = [];

    foreach ($array AS $key => $value) {

        if (!is_array($value)) {
            unset($array[$key]);
            $newArray[camelToUnderscore($key)] = $value;
        } else {
            unset($array[$key]);
            $newArray[camelToUnderscore($key)] = keysCamelToUnderscore($value);
        }
    }

    return $newArray;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
n00b
  • 16,088
  • 21
  • 56
  • 72
  • 2
    Nope, it's primarily about updating array keys. – n00b Mar 05 '15 at 08:25
  • 1
    To change an array key, you have to create a duplicate value entry with the new key, then unset the old key – Mark Baker Mar 05 '15 at 08:28
  • An alternative would be to use array_flip(), update the values, then array_flip() again – Mark Baker Mar 05 '15 at 08:29
  • Or possibly to use something like array_combine() with array_keys() and array_values(), modifying the keyset before combining back again – Mark Baker Mar 05 '15 at 08:29
  • @MarkBaker I have arrays in the area of 20 to 50 indexes... Would you say performance does not need to be considered? – n00b Mar 05 '15 at 08:30
  • `$before = ['ThisIsATest' => 'Something', 'cheeseCake' => 'Something else']; $before = array_combine( array_map( function ($value) { return strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $value)); }, array_keys($before) ), $before ); var_dump($before);` – Mark Baker Mar 05 '15 at 09:56

0 Answers0