У меня есть массив PHP, который я хотел бы дублировать, но только копировать элементы из массива, ключи которого отображаются в другом массиве.
Вот мои массивы:
$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';
Я мог бы просто прокрутить массив данных следующим образом:
foreach ($data as $key => $value) { if ( in_array($key, $keys_to_copy)) { $copied_data[$key] = $value; } }
Но это будет происходить внутри цикла, который извлекает данные из набора результатов MySQL. Таким образом, это будет цикл, вложенный в цикл данных MySQL. Я обычно стараюсь избегать вложенных циклов, если нет возможности использовать встроенные функции массива PHP для получения результата, который я ищу. Но я также устал от наличия вложенного цикла в цикле данных MySQL, я не хочу, чтобы MySQL зависал.
Вероятно, я беспокоюсь о производительности вложенного цикла без необходимости, поскольку я никогда не буду делать этого более чем на пару сотен строк данных и, возможно, 10 ключей.
Но я хотел бы знать, есть ли способ сделать это со встроенными функциями PHP.
Я посмотрел на array_intesect_key()
но это не совсем так, потому что у моего массива $keys_to_copy
есть мои нужные ключи как значения массива, а не ключи.
У кого-нибудь есть идеи?
Приветствия, B
Я справился с этим – у меня почти было это выше. Я думал, что я отправлю ответ в любом случае для полноты. Надеюсь, это поможет кому-то!
array_intersect_key($data, array_flip($keys_to_copy))
Используйте array_flip()
для переключения $keys_to_copy
чтобы он мог использоваться внутри array_intersect_keys()
Я проведу несколько тестов для сравнения производительности между ручным циклом выше, с этим ответом. Я ожидал бы, что встроенные функции будут быстрее, но они могут быть довольно равными. Я знаю, что массивы сильно оптимизированы, поэтому я уверен, что они будут близки.
РЕДАКТИРОВАТЬ:
Я выполнил некоторые тесты, используя PHP CLI, чтобы сравнить код foreach()
в моем вопросе с кодом в моем ответе выше. Результаты довольно поразительны.
Вот код, который я использовал для сравнения, который, на мой взгляд, действителен:
<?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"; ?>
И результаты …
foreach: 662.217s
array_intersect_key: 0.099s
Таким образом, намного быстрее загружает элементы массива для использования функций массива PHP, а не foreach
. Я думал, что это будет быстрее, но не так!
Почему бы не загрузить весь массив результатов в массив, а затем начать обработку с помощью вложенных циклов?
$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; } }