2009-07-21 15 views
7

¿Existe una forma "mejor" (función incorporada, mejor algoritmo) para normalizar el caso de todas las claves en una matriz de PHP? Bucle sin embargo y la creación de una nueva matriz funcionaNormalizar el caso de las teclas de matriz en 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'); 
    } 

} 

pero parece que estos deben ser una forma de hacerlo "en su lugar".

Actualización: Parece que hay un built-in, el nombre no es engañosamente pero de alguna manera extrañado por mí array_change_key_case. Todavía sería interesante ver enfoques algorítmicos que te permitan manejar mejor lo que sucede cuando presionas las teclas "duplicadas".

+0

Para el enfoque algorítmico me gustaría ir con la versión "pragmática" de soulmerge a continuación. – acrosman

+0

[Esta publicación] (http://blog.jterminal.com/2014/07/change-the-case-of-all-keys-in-an-array-with-array_change_key_case-function-in-php.html) explica lo que necesita – Jasir

Respuesta

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

Usted podría utilizar array_change_key_case(). Esto puede hacer que se sobrescriban las teclas de matriz, por lo que querrá comparar los tamaños de matriz usando count() antes y después de hacer el cambio de mayúscula. Debido a los recuentos(), no estoy seguro de si este método le daría un mejor rendimiento o no, tendría que compararlo.

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

me encontré con que las funciones incorporadas son mucho más rápido que los bucles al procesar grandes conjuntos. Esto puede hacer lo que quiera (código no probado):

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

EDITAR O el enfoque pragmático (debería ser mucho más rápido):

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

Sí, las construcciones casi siempre serán más rápidas. Cuando es Compiled C vs. PHP Opt-Code, adivina quién gana :) –

0

Apoyo a las matrices multidimensionales, inspirado en this PHP manual comment:

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

Para un mejor rendimiento, utiliza la función PHP nativa array_change_key_case().

Cuestiones relacionadas