luqo33 luqo33 - 2 months ago 21
PHP Question

Convert array keys from underscore_case to camelCase recursively

I had to come up with a way to convert array keys using undescores (underscore_case) into camelCase. This had to be done recursively since I did not know what arrays will be fed to the method.

I came up with this:

private function convertKeysToCamelCase($apiResponseArray)
{
$arr = [];
foreach ($apiResponseArray as $key => $value) {
if (preg_match('/_/', $key)) {
preg_match('/[^_]*/', $key, $m);
preg_match('/(_)([a-zA-Z]*)/', $key, $v);
$key = $m[0] . ucfirst($v[2]);
}


if (is_array($value))
$value = $this->convertKeysToCamelCase($value);

$arr[$key] = $value;
}
return $arr;
}


It does the job, but I think it could be done much better and more concisely. Multiple calls to
preg_match
and then concatenation just look weird.

Do you see a way to tidy up this method?
And more importantly, is it possible at all to do the same operation with just one call to
preg_match
? How would that look like?

Answer

The recursive part cannot be further simplified or prettified.

But the conversion from underscore_case (also known as snake_case) and camelCase can be done in several different ways:

$key = 'snake_case_key';
// split into words, uppercase their first letter, join them, 
// lowercase the very first letter of the name
$key = lcfirst(implode('', array_map('ucfirst', explode('_', $key))));

or

$key = 'snake_case_key';
// replace underscores with spaces, uppercase first letter of all words,
// join them, lowercase the very first letter of the name
$key = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key))));

or

$key = 'snake_case_key':
// match underscores and the first letter after each of them,
// replace the matched string with the uppercase version of the letter
$key = preg_replace_callback(
    '/_([^_])/',
    function (array $m) {
        return ucfirst($m[1]);
    },
    $key
);

Pick your favorite!

Comments