variable una sufijos sufijo prefijos prefijo poner para palabras palabra niños muchas matriz matrices manejo lista hacer generar ejemplos dibujar con como celdas asociativas array agregar php arrays

php - una - ¿La forma más rápida de agregar prefijo a las claves de matriz?



prefijos y sufijos para niños (8)

¿Cuál es la forma más rápida de agregar prefijos de cadena a las claves de matriz?

Entrada

$array = array( ''1'' => ''val1'', ''2'' => ''val2'', );

Salida necesaria:

$array = array( ''prefix1'' => ''val1'', ''prefix2'' => ''val2'', );


Descubrí que PHPBench no es una buena fuente de puntos de referencia no triviales. Entonces, a menos que esté realmente interesado en postularse for(....); no va a mostrar correctamente qué sintaxis será más rápida. He reunido un punto de referencia simple para demostrar que foreach es en realidad el más rápido cuando usa la clave y el valor durante la iteración.

Es muy importante forzar a PHP a leer los valores de una iteración de bucle, o hará todo lo posible para optimizarlos. En el siguiente ejemplo, uso la función doNothing para forzar a PHP a calcular la clave y el valor cada vez. El uso de doNothing hará que se aplique una sobrecarga a cada bucle, pero será igual para cada bucle, ya que el número de llamadas será el mismo.

Realmente no estaba tan sorprendido de que foreach llegado a la cima, ya que es la construcción del lenguaje para iterar un diccionario.

$array = range( 0, 1000000 ); function doNothing( $value, $key ) {;} $t1_start = microtime(true); foreach( $array as $key => $value ) { doNothing( $value, $key ); } $t1_end = microtime(true); $t2_start = microtime(true); $array_size = count( $array ); for( $key = 0; $key < $array_size; $key++ ) { doNothing( $array[$key], $key ); } $t2_end = microtime(true); //suggestion from PHPBench as the "fastest" way to iterate an array $t3_start = microtime(true); $key = array_keys($array); $size = sizeOf($key); for( $i=0; $i < $size; $i++ ) { doNothing( $key[$i], $array[$key[$i]] ); } $t3_end = microtime(true); $t4_start = microtime(true); array_walk( $array, "doNothing" ); $t4_end = microtime(true); print "Test 1 ".($t1_end - $t1_start)."/n". //Test 1 0.342370986938 "Test 2 ".($t2_end - $t2_start)."/n". //Test 2 0.369848966599 "Test 3 ".($t3_end - $t3_start)."/n". //Test 3 0.78616809845 "Test 4 ".($t4_end - $t4_start)."/n"; //Test 4 0.542922019958

Edición: estoy usando PHP 5.3 en Mac OSX 10.6 de 64 bits


Me di cuenta de una solución de una línea:

array_walk($array, create_function(''$value, &$key'', ''$key = "prefix" . $key;''));


Me gustaría crear una matriz completamente nueva y crear sus nuevas claves. Eso tiene que ser más rápido que desactivar todas las claves no deseadas;

$prefixed_array = array(); foreach ($array as $key => $value) { $prefixed_array[ $prefix . $key] = $value; }

Y si quieres hacer algún otro "afijo".

function array_affix_keys($affix, Array $array, $type = ''prefix'', $options = array()){ $affixed_array = array(); if($type ==''prefix''){ foreach ($array as $key => $value) {$affixed_array[ $affix . $key] = $value;} return $affixed_array; } if($type ==''suffix''){ foreach ($array as $key => $value) {$affixed_array[$key . $affix ] = $value;} return $affixed_array; } if($type ==''circumfix''){ if(is_array($affix) && count($affix) == 2){ foreach ($array as $key => $value) { $affixed_array[ $affix[0] . $key . $affix[1] ] = $value; } } return $affixed_array; } if($type == ''simulfix'' && isset($options[''phonemes''])){ foreach ($array as $key => $value) { $affixed_array[ str_replace($options[''phonemes''], $affix, $key) ] = $value;} return $affixed_array; } return $array; } $prefixed = array_affix_keys(''prefix_'', $array); $prefixed = array_affix_keys(''prefix_'', $array, ''prefix''); $suffixed = array_affix_keys(''_suffix'', $array, ''suffix''); $circumfixed = array_affix_keys(array(''prefix'', ''suffix''), $array, ''circumfix''); $simulfix = array_affix_keys(''replace'', $array, ''simulfix'', array(''phonemes'' => ''find''));


Otra forma de lograrlo es con array_flip ()

<?php $data = array_flip($data); foreach($data as $key => &$val) { $val = "prefix" . $val; } $data = array_flip($data);


Podría hacer esto en una larga línea, supongo:

$array = array_combine( array_map(function($k){ return ''prefix''.$k; }, array_keys($array)), $array );

O para versiones de PHP anteriores a 5.3:

$array = array_combine( array_map(create_function(''$k'', ''return "prefix".$k;''), array_keys($array)), $array );

Probablemente hay docenas de maneras de hacer esto sin embargo:

foreach ($array as $k => $v) { $array[''prefix_''.$k] = $v; unset($array[$k]); }


Si no quieres usar para bucle puedes hacerlo:

// function called by array_walk to change the $value in $key=>$value. function myfunction(&$value,$key) { $value="prefix$value"; } $keys = array_keys($array); // extract just the keys. array_walk($keys,"myfunction"); // modify each key by adding a prefix. $a = array_combine($keys,array_values($array)); // combine new keys with old values.

No creo que esto sea más eficiente que el bucle for . Supongo que array_walk utilizará internamente un bucle y también hay una sobrecarga de llamada a la función aquí.


function array_key_prefix_suffix(&$array,$prefix='''',$suffix=''''){ $key_array = array_keys($array); $key_string = $prefix.implode($suffix.'',''.$prefix,$key_array).$suffix; $key_array = explode('','', $key_string); $array = array_combine($key_array, $array); }

Esto está implementado y funciona muy bien.


function keyprefix($keyprefix, Array $array) { foreach($array as $k=>$v){ $array[$keyprefix.$k] = $v; unset($array[$k]); } return $array; }

El uso de array_flip no conservará los valores vacíos o nulos. Se podría agregar un código adicional en el caso improbable de que la clave prefijada ya exista.