2012-03-16 11 views
13

Çoğaltmak istediğim bir PHP dizilim var, ancak yalnızca anahtarları başka bir dizide görünen diziden öğeleri kopyala. İşte PHP dizisi yerleşik tuşları, belirli işlevleri kopyalamak? İç içe döngü performansı?

benim diziler şunlardır:

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

elimden bu gibi veri dizisi ile sadece döngü:

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

Ama bu MySQL sonucu veri alıyor bir döngü içine neler olacak ayarlayın. Yani bir MySQL veri döngüsünde iç içe bir döngü olurdu. Normalde aradığım sonucu elde etmek için PHP'nin yerleşik dizi işlevlerini kullanmanın bir yolu olmadıkça yuvalanmış döngülerden kaçınıyorum. Ama aynı zamanda bir MySQL veri döngüsünde yuvalanmış bir döngüye sahip olmaktan bıktım, MySQL'in etrafta takılı kalmasını istemiyorum.

İç içe döngü performansı konusunda gereksiz yere endişeleniyorum, çünkü bunu birkaç yüz satırlık veriden ve 10 anahtardan fazlası için yapamayacağım.

Ancak, yerleşik PHP işlevleriyle bunu yapmanın bir yolu olup olmadığını bilmek istiyorum.
array_intesect_key()'a bir göz attım, ancak bu tam olarak yapmıyor çünkü $keys_to_copy dizim tuşlarımdan ziyade dizi değerleri olarak istenen anahtarlarıma sahip.

Herhangi bir fikri olan var mı?

Alkış, B

+1

Neden ana anahtar olarak '$ keys_to_copy' kullanmıyorsunuz? – Yoshi

cevap

28

çözdüm - Neredeyse o above.I ben şeyiyle zaten yanıt sonrası düşündüm vardı. Umarım bu birisine yardım eder!

array_intersect_key($data, array_flip($keys_to_copy))

Kullanım array_flip()

$keys_to_copy yüzden bu cevaba, yukarıdaki manuel döngü arasında performans karşılaştırması için bazı testler edeceğiz array_intersect_keys()

içerisinde kullanılabilecek geçin. Yerleşik işlevlerin daha hızlı olmasını beklerim ancak oldukça eşit olabilirler. Dizilerin ağır bir şekilde optimize edildiğini biliyorum, bu yüzden yakın olacağından eminim.

DÜZENLEME: Yukarıdaki cevabım kodu ile benim söz konusu foreach() kodunu karşılaştırmak için PHP CLI kullanarak bazı kriterler yayınlanmış olan
. Sonuçlar oldukça şaşırtıcı.

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

Ve sonuç ...
foreach: 662.217s
array_intersect_key: 0.099s

Yani çok oluyor
İşte geçerlidir düşünüyorum ben kriter için kullanılan kod, var foreach yerine PHP dizi işlevlerini kullanmak için dizi öğelerinin yükleri üzerinde daha hızlı. Daha hızlı olacağını düşündüm ama o kadar değil!

+7

Bu, SO'nın tüm amacı: Başkalarına yardım etmek. Kendi sorunun cevabını verseniz bile. Bunu yapmanın doğru yolu budur. – JYelton

+1

İşlemlerin sırasını değiştirirseniz, "foreach" daha hızlı olur. 'foreach ($ keys_to_copy AS $ tuşu) {$ copied_data [$ key] = $ data [$ key];}' –

0

Neden tüm sonuç kümesini bir diziye yüklemiyorsunuz, sonra iç içe döngülerle işlemeye başlıyorsunuz?

$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; 
    } 
} 
İlgili konular