2012-03-16 11 views
13

Tengo una matriz de PHP que me gustaría duplicar pero solo copio elementos de la matriz cuyas claves aparecen en otra matriz.PHP array ¿copiar ciertas teclas, funciones integradas? ¿Desempeño anidado del bucle?

Éstos son mis matrices:

$data[123] = 'aaa'; 
$data[423] = 'bbb'; 
$data[543] = 'ccc'; 
$data[231] = 'ddd'; 
$data[642] = 'eee'; 
$data[643] = 'fff'; 
$data[712] = 'ggg'; 
$data[777] = 'hhh'; 

$keys_to_copy[] = '123'; 
$keys_to_copy[] = '231'; 
$keys_to_copy[] = '643'; 
$keys_to_copy[] = '712'; 
$keys_to_copy[] = '777'; 

$copied_data[123] = 'aaa'; 
$copied_data[231] = 'ddd'; 
$copied_data[643] = 'fff'; 
$copied_data[712] = 'ggg'; 
$copied_data[777] = 'hhh';

acabo de poder recorrer la matriz de datos de esta manera:

foreach ($data as $key => $value) { 
    if (in_array($key, $keys_to_copy)) { 
    $copied_data[$key] = $value; 
    } 
}

Pero esto va a ocurrir dentro de un bucle que está recuperando datos de resultado de MySQL conjunto. Entonces sería un bucle anidado dentro de un bucle de datos MySQL. Normalmente intento evitar los bucles anidados a menos que no haya forma de utilizar las funciones de matriz incorporadas de PHP para obtener el resultado que estoy buscando. Pero también estoy cansado de tener un bucle anidado dentro de un bucle de datos MySQL, no quiero mantener MySQL dando vueltas.

Probablemente estoy preocupado innecesariamente por el rendimiento del ciclo anidado, ya que nunca lo haré por más de un par de cientos de filas de datos y tal vez 10 claves.

Pero me gustaría saber si hay una forma de hacerlo con las funciones integradas de PHP.
Eché un vistazo a array_intesect_key() pero eso no acaba de hacer, porque mi matriz $keys_to_copy tiene mis claves deseadas como valores de matriz en lugar de claves.

¿Alguien tiene alguna idea?

Saludos, B

+1

¿Por qué no utiliza '' keys_to_copy' como el bucle principal? – Yoshi

Respuesta

28

lo resolví - casi lo tenía above.I pensé que había puesto la respuesta de todos modos para la integridad. ¡Espero que esto ayude a alguien!

array_intersect_key($data, array_flip($keys_to_copy))

Uso array_flip() para cambiar $keys_to_copy por lo que se puede utilizar dentro array_intersect_keys()

voy a correr algunas pruebas para comparar el rendimiento entre el bucle manual de arriba, a esta respuesta. Esperaría que las funciones integradas fueran más rápidas pero podrían ser bastante iguales. Sé que las matrices están muy optimizadas, así que estoy seguro de que estarán cerca.

EDIT:
he corrido algunos puntos de referencia usando PHP CLI para comparar el código foreach() en mi pregunta con el código en mi respuesta anterior. Los resultados son bastante asombrosos.
Aquí está el código que solía referencia, que creo que es válido:

<?php 
ini_set('max_execution_time', 0);//NOT NEEDED FOR CLI 

// BUILD RANDOM DATA ARRAY 
$data = array(); 
while (count($data) <= 200000) { 
    $data[rand(0, 500000)] = rand(0, 500000); 
} 
$keys_to_copy = array_rand($data, 100000); 

// FOREACH 
$timer_start = microtime(TRUE); 
foreach ($data as $key => $value) { 
    if (in_array($key, $keys_to_copy)) { 
     $copied_data[$key] = $value; 
    } 
} 
echo 'foreach: '.(microtime(TRUE) - $timer_start)."s\r\n"; 

// BUILT-IN ARRAY FUNCTIONS 
$timer_start = microtime(TRUE); 
$copied_data = array_intersect_key($data, array_flip($keys_to_copy)); 
echo 'built-in: '.(microtime(TRUE) - $timer_start)."s\r\n"; 
?>

Y los resultados ...
foreach: 662.217s
array_intersect_key: 0.099s

lo que es mucho más rápido sobre cargas de elementos de matriz para usar las funciones de matriz de PHP en lugar de foreach. ¡Pensé que sería más rápido pero no tanto!

+7

Ese es el propósito de SO: ayudar a otros. Incluso si terminas respondiendo tu propia pregunta. Esta es la forma correcta de hacerlo. – JYelton

+1

Si cambia el orden de sus operaciones, el 'foreach' se vuelve más rápido. 'foreach ($ keys_to_copy clave AS $) {$ datos_copiados [$ clave] = $ datos [$ clave];}' –

0

¿Por qué no cargar todo el conjunto de resultados en una matriz, y luego comenzar a procesar con bucles anidados?

$query_result = mysql_query($my_query) or die(mysql_error()); 
$query_rows = mysql_num_rows($query_result); 
for ($i = 0; $i < $query_rows; $i++) 
{ 
    $row = mysql_fetch_assoc($query_result); 
    // 'key' is the name of the column containing the data key (123) 
    // 'value' is the name of the column containing the value (aaa) 
    $data[$row['key']] = $row['value']; 
} 
foreach ($data as $key => $value) 
{ 
    if (in_array($key, $keys_to_copy)) 
    { 
     $copied_data[$key] = $value; 
    } 
} 
Cuestiones relacionadas