2012-03-16 14 views
13

Mam tablicę PHP, którą chciałbym powielić, ale tylko skopiować elementy z tablicy, której klucze pojawiają się w innej tablicy.Tablica PHP kopiuje określone klucze, wbudowane funkcje? Zagnieżdżona wydajność pętli?

Oto moje tablice:

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

mogłem tylko pętla przez tablicę danych jak poniżej:

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

Ale to będzie się działo wewnątrz pętli, która jest pobieranie danych z wyniku MySQL zestaw. Więc byłoby pętlą zagnieżdżoną w pętli danych MySQL. Zazwyczaj staram się unikać zagnieżdżonych pętli, chyba że nie ma możliwości użycia wbudowanych funkcji tablic PHP, aby uzyskać wynik, którego szukam. Ale jestem również zmęczony posiadaniem zagnieżdżonej pętli w pętli danych MySQL, nie chcę utrzymywać MySQL w ruchu.

Prawdopodobnie niepotrzebnie niepotrzebnie zagnieżdżona wydajność pętli, ponieważ nigdy nie będę tego robił dla więcej niż kilkuset wierszy danych i może 10 kluczy.

Ale chciałbym wiedzieć, czy jest sposób na to zrobić z wbudowanymi funkcjami PHP.
Spojrzałem na array_intesect_key(), ale to nie całkiem to robi, ponieważ moja tablica $keys_to_copy ma moje pożądane klucze jako wartości tablicowe zamiast kluczy.

Ktoś ma jakieś pomysły?

Cheers, B

+1

Dlaczego nie użyjesz '$ keys_to_copy' jako głównej pętli? – Yoshi

Odpowiedz

28

poradziłem sobie - Prawie miałem to above.I myślałem, że pisać odpowiedź w każdym razie pod względem kompletności. Mam nadzieję, że to pomoże komuś!

array_intersect_key($data, array_flip($keys_to_copy))

użytkowania array_flip() przełączyć $keys_to_copy dzięki czemu może być używany wewnątrz array_intersect_keys()

będę przeprowadzić kilka testów, aby porównać wydajność między ręcznym pętli powyżej, do tej odpowiedzi. Spodziewałbym się, że wbudowane funkcje będą szybsze, ale mogą być całkiem równe. Wiem, że tablice są mocno zoptymalizowane, więc jestem pewien, że będzie blisko.

EDIT:
Mam biegać kilka wzorców używając PHP CLI porównać kod foreach() na moje pytanie z kodem w mojej odpowiedzi powyżej. Wyniki są zdumiewające.
Oto kod użyłem do benchmarku, który moim zdaniem jest ważne:

<?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"; 
?>

A wyniki ...
foreach: 662.217s
array_intersect_key: 0.099s

Więc to znacznie szybsze ładowanie elementów tablicy do korzystania z funkcji tablic PHP, a nie foreach. Myślałem, że będzie szybciej, ale nie aż tak!

+7

Taki jest cel SO: pomaganie innym. Nawet jeśli skończysz odpowiadać na własne pytanie. To jest właściwy sposób, aby to zrobić. – JYelton

+1

Jeśli odwrócisz kolejność operacji, "foreach" stanie się szybszy. 'foreach (klucz $ keys_to_copy AS $) {$ copied_data [klucz $] = $ dane [klucz $];}' –

0

Dlaczego nie załadować całego zestawu wyników do tablicy, a następnie rozpocząć przetwarzanie za pomocą zagnieżdżonych pętli?

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