Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Normalize the case of array keys in PHP

Is there a "better" way (built-in function, better algorithm) to normalize the case of all the keys in a PHP array? Looping though and creating a new array works

$new = array();
foreach( $old as $key=>$value) {
    $key = strToLower($key);
    if(!array_key_exists($key,$new) {
        $new[$key] = $value;
    } 
    else {
        throw new Exception('Duplicate Key Encountered');
    }

}

but it seems like these should be a way to do this "in place".

Update: It looks like there is a built in, the not deceptively named yet somehow missed by me array_change_key_case. I'd still be interesting in seeing algorithmic approaches that would let you better handle what happens when you hit "duplicate" keys.

like image 447
Alan Storm Avatar asked Jul 21 '09 20:07

Alan Storm


2 Answers

I believe array_change_key_case does what you're looking for.

http://us3.php.net/manual/en/function.array-change-key-case.php

like image 170
acrosman Avatar answered Sep 22 '22 05:09

acrosman


I found that builtin functions are much faster than loops when processing large arrays. This might do what you want (untested code):

$lowerCaseKeys = array_map('strtolower', array_keys($array));
$duplicates = array_filter(array_count_values($lowerCaseKeys), create_function('$count', 'return $count > 1;'));
if (!empty($duplicates)) {
    throw new Exception('duplicate keys found: ' . implode(',', array_keys($duplicates)));
}
# Recreate the array with lower-case keys
$array = array_combine($lowerCaseKeys, array_values($array));

EDIT Or the pragmatic approach (should be much faster):

$lowerCaseKeyArray = array_change_key_case($array);
if (count($lowerCaseKeyArray) !== count($array)) {
    # You can extract the duplicate keys here as above, if you like
    throw new Exception('duplicate keys found!');
}
like image 32
soulmerge Avatar answered Sep 22 '22 05:09

soulmerge