2012-03-16 27 views
13

Tôi có một mảng PHP mà tôi muốn sao chép nhưng chỉ sao chép các phần tử từ mảng có khóa xuất hiện trong mảng khác.Mảng PHP sao chép các phím nhất định, các chức năng tích hợp sẵn? Hiệu suất vòng lặp lồng nhau?

Dưới đây là mảng của tôi:

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

tôi có thể chỉ lặp qua mảng dữ liệu như thế này:

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

Nhưng điều này sẽ được diễn ra bên trong một vòng lặp mà là lấy dữ liệu từ kết quả MySQL bộ. Vì vậy, nó sẽ là một vòng lặp lồng nhau trong vòng lặp dữ liệu MySQL. Tôi thường thử và tránh các vòng lồng nhau trừ khi không có cách nào để sử dụng các hàm mảng dựng sẵn của PHP để có được kết quả mà tôi đang tìm kiếm. Nhưng tôi cũng mệt mỏi vì có một vòng lặp lồng nhau trong vòng lặp dữ liệu MySQL, tôi không muốn giữ MySQL treo xung quanh.

Tôi có thể lo lắng về hiệu suất vòng lặp lồng nhau không cần thiết vì tôi sẽ không bao giờ làm điều này cho hơn một trăm hàng trăm dữ liệu và có thể 10 khóa.

Nhưng tôi muốn biết liệu có cách nào để thực hiện điều này với các hàm PHP tích hợp hay không.
Tôi đã xem array_intesect_key() nhưng điều đó không thực hiện được, vì mảng $keys_to_copy của tôi có các khóa mong muốn của tôi dưới dạng giá trị mảng thay vì khóa.

Bất kỳ ai có ý tưởng nào?

Chúc mừng, B

+1

Tại sao bạn không sử dụng '$ keys_to_copy' làm vòng lặp chính? – Yoshi

Trả lời

28

Tôi đã làm việc đó - Tôi gần như đã có nó ở trên.Tôi nghĩ rằng tôi đã đăng câu trả lời để hoàn thành. Mong rằng nó giúp ai đó thoát!

array_intersect_key($data, array_flip($keys_to_copy))

Sử dụng array_flip() chuyển $keys_to_copy để nó có thể được sử dụng trong array_intersect_keys()

tôi sẽ chạy một số xét nghiệm để so sánh hiệu suất giữa vòng tay trên, câu trả lời này. Tôi hy vọng các chức năng tích hợp sẽ nhanh hơn nhưng chúng có thể khá bình đẳng. Tôi biết mảng được tối ưu hóa rất nhiều vì vậy tôi chắc chắn rằng nó sẽ được đóng lại.

EDIT:
tôi đã chạy một số tiêu chuẩn sử dụng PHP CLI để so sánh các mã foreach() trong câu hỏi của tôi với mã trong câu trả lời của tôi ở trên. Kết quả khá đáng kinh ngạc.
Dưới đây là đoạn code tôi sử dụng để benchmark, mà tôi nghĩ là hợp lệ:

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

Và kết quả ...
foreach: 662.217s
array_intersect_key: 0.099s

Vì vậy, nó nhiều nhanh hơn tải các phần tử mảng để sử dụng các hàm mảng PHP thay vì foreach. Tôi nghĩ nó sẽ nhanh hơn nhưng không phải thế!

+7

Đó là toàn bộ mục đích của SO: để giúp đỡ người khác. Ngay cả khi bạn gió trả lời câu hỏi của riêng bạn. Đây là cách đúng để làm điều đó. – JYelton

+1

Nếu bạn lật thứ tự các hoạt động của mình, 'foreach' trở nên nhanh hơn. 'foreach ($ keys_to_copy AS $ key) {$ copied_data [$ key] = $ dữ liệu [$ key];}' –

0

Tại sao không tải toàn bộ tập kết quả vào một mảng, sau đó bắt đầu xử lý với vòng lặp lồng nhau?

$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; 
    } 
} 
Các vấn đề liên quan