在PHP中规范化数组键的大小写

时间:2021-08-13 10:45:30

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

是否有一种“更好”的方式(内置函数,更好的算法)来规范化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');
    }

}

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.

更新:看起来有一个内置的,没有欺骗性命名但我错过了array_change_key_case。我仍然很有兴趣看到算法方法可以让你更好地处理当你点击“重复”键时发生的事情。

5 个解决方案

#1


13  

I believe array_change_key_case does what you're looking for.

我相信array_change_key_case可以满足您的需求。

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

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

#2


4  

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

#3


3  

You could use array_change_key_case(). This can cause array keys to be overwritten, so you would want to compare the array sizes using count() before and after you do the key case change. Because of the counts(), I'm not sure if this method would give you better performance or not, you'd have to benchmark it.

你可以使用array_change_key_case()。这可能会导致数组键被覆盖,因此您需要在执行键案例更改之前和之后使用count()比较数组大小。由于count(),我不确定这种方法是否能提供更好的性能,你必须对它进行基准测试。

$new = array_change_key_case($old, CASE_LOWER);
if (count($new) < count($old)) {
    throw new Exception("Duplicate key encountered.");
}

#4


0  

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;
}

#5


0  

Support for multidimensional arrays, inspired from this PHP manual comment:

支持多维数组,受益于此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;
}

For better performance, it uses the native array_change_key_case() PHP function.

为了获得更好的性能,它使用本机array_change_key_case()PHP函数。

#1


13  

I believe array_change_key_case does what you're looking for.

我相信array_change_key_case可以满足您的需求。

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

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

#2


4  

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

#3


3  

You could use array_change_key_case(). This can cause array keys to be overwritten, so you would want to compare the array sizes using count() before and after you do the key case change. Because of the counts(), I'm not sure if this method would give you better performance or not, you'd have to benchmark it.

你可以使用array_change_key_case()。这可能会导致数组键被覆盖,因此您需要在执行键案例更改之前和之后使用count()比较数组大小。由于count(),我不确定这种方法是否能提供更好的性能,你必须对它进行基准测试。

$new = array_change_key_case($old, CASE_LOWER);
if (count($new) < count($old)) {
    throw new Exception("Duplicate key encountered.");
}

#4


0  

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;
}

#5


0  

Support for multidimensional arrays, inspired from this PHP manual comment:

支持多维数组,受益于此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;
}

For better performance, it uses the native array_change_key_case() PHP function.

为了获得更好的性能,它使用本机array_change_key_case()PHP函数。