Нормализовать регистр ключей массива в PHP - PullRequest
7 голосов
/ 22 июля 2009

Есть ли "лучший" способ (встроенная функция, лучший алгоритм), чтобы нормализовать регистр всех ключей в массиве PHP? Цикл и создание нового массива работает

$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');
    }

}

но похоже, что это должен быть способ сделать это "на месте".

Обновление : Похоже, что есть встроенный, не обманчиво названный, но каким-то образом пропущенный мной array_change_key_case. Мне все еще было бы интересно увидеть алгоритмические подходы, которые позволили бы вам лучше справляться с тем, что происходит, когда вы нажимаете «дублирующие» ключи.

Ответы [ 5 ]

13 голосов
/ 22 июля 2009

Я считаю, array_change_key_case делает то, что вы ищете.

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

4 голосов
/ 22 июля 2009

Я обнаружил, что встроенные функции намного быстрее, чем циклы при обработке больших массивов. Это может делать то, что вы хотите (непроверенный код):

$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));

РЕДАКТИРОВАТЬ Или прагматический подход (должен быть намного быстрее):

$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!');
}
3 голосов
/ 22 июля 2009

Вы можете использовать array_change_key_case () . Это может привести к перезаписи ключей массива, поэтому вы захотите сравнить размеры массива, используя count() до и после изменения регистра ключа. Из-за countts () я не уверен, что этот метод даст вам лучшую производительность или нет, вам придется его тестировать.

$new = array_change_key_case($old, CASE_LOWER);
if (count($new) < count($old)) {
    throw new Exception("Duplicate key encountered.");
}
0 голосов
/ 14 декабря 2011

Поддержка многомерных массивов, вдохновленная этим комментарием к PHP-руководству :

function array_change_key_case_recursive($input, $case = CASE_LOWER)
{
    if (!is_array($input))
    {
        trigger_error("Invalid input array '{$array}'", E_USER_NOTICE);
        return false;
    }

    if (!in_array($case, array(CASE_UPPER, CASE_LOWER)))
    {
        trigger_error("Case parameter '{$case}' is invalid.", E_USER_NOTICE);
        return false;
    }

    $input = array_change_key_case($input, $case);

    foreach($input as $key => $array)
        if(is_array($array))
            $input[$key] = array_change_key_case_recursive($array, $case);

    return $input;
}

Для повышения производительности он использует встроенную функцию array_change_key_case () PHP.

0 голосов
/ 22 июля 2009
foreach(array_keys($old) as $key) {
  $lower = strtolower($key);
  //if key is already lower case, do nothing
  if($key == $lower)
    continue;
  $value = $old[$key];
  unset($old[$key]);
  $old[$lower] = $value;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...