2

I'm trying to create a function to transform all keys (from / to) camel case in a Multidemnsional array. The problem is when I have an array of array the inner array comes out as the last element of the array and I can't figure out why..

Here is the function:

function transformKeys(&$array, $direction = 'to')
{
    if (is_array($array)) {
        foreach (array_keys($array) as $key) {
            $value = &$array[$key];
            unset($array[$key]);
            if ($direction == 'to')
                $transformedKey = toCamelCase($key);
            else 
                $transformedKey = fromCamelCase($key);


            if (is_array($value))
                transformKeys($value, $direction);

            if (isset($array[$transformedKey]) && is_array($array[$transformedKey])) {
                $array[$transformedKey] = array_merge($array[$transformedKey], $value);
            }
            else
                $array[$transformedKey] = $value;
            unset($value);
        }

    }
    return $array;
  }

function toCamelCase($string, $sepp = '_')
{
    $str = str_replace(' ', '', ucwords(str_replace($sepp, ' ', $string)));
    $str[0] = strtolower($str[0]);
    return $str;
}

function fromCamelCase($string, $sepp = '_')
{
    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($sepp, $ret);
}

The array is something like this..

 {
    "id": 23,
    "name": "FOO SA",
    "taxIdentifier_id": "309",
    "activityType": "UTILITY",
    "currencyCode": "USD",
    "contacts": [
        {
            "id": 7,
            "firstName": "Bla",
            "lastName": "Bla",
            "gender": "M",
            "supplierId": 23
        },
        {
            "id": 8,
            "firstName": "Another",
            "lastName": "Value",
            "gender": "M",
            "supplierId": 23
        }
    ]
}

and the result...

Array
(
    [id] => 23
    [name] => FOO SA
    [tax_identifier_id] => 309
    [activity_type] => UTILITY
    [currency_code] => USD
    [contacts] => Array
        (
            [] => Array
                (
                    [id] => 8
                    [first_name] => Another
                    [last_name] => Value
                    [gender] => M
                    [supplier_id] => 23
                )

        )

)

Any Ideas??

Thanks!

2
  • is the source in JSON format? Commented Jul 22, 2013 at 22:40
  • Yes source comes from a json string.. Commented Jul 22, 2013 at 23:51

1 Answer 1

2

Your fromCamelCase() function gives wrong values for numeric array keys:

var_dump(fromCamelCase(1)); // string(0) ""

Here's an implementation that doesn't suffer from such a drawback:

function fromCamelCase($key) 
{
    return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $key));
}

I've also made some simplifications to your design; instead of using fixed functions I've made it generic:

function array_changekey_recursive(array &$array, $callback)
{
    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            array_changekey_recursive($value, $callback);
        }

        $new_key = call_user_func($callback, $key);
        // only update where necessary
        if (strcmp($new_key, $key) != 0) {
            unset($array[$key]);
            $array[$new_key] = $value;
        }
    }
}

To call it:

array_changekey_recursive($arr, 'fromCamelCase');
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, this worked like a charm! The problem was with the "fromCamelCase" function, although your implementation of the changeKey is simpler. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.