2012-03-16 2 views
13

PHP 배열을 복사하고 싶지만 다른 배열에 키가있는 배열의 요소 만 복사하면됩니다. 여기 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';

I 수 같은 데이터 배열을 통해 단지 루프 :

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

그러나 이것은 MySQL의 결과에서 데이터를 검색하는 루프 내에서 발생한다 세트. 따라서 이것은 MySQL 데이터 루프 내에 중첩 된 루프가 될 것입니다. 필자가 찾고있는 결과를 얻기 위해 PHP의 내장 배열 함수를 사용할 방법이 없다면 일반적으로 중첩 된 루프는 사용하지 않는 것이 좋습니다. 그러나 MySQL 데이터 루프 내에서 중첩 된 루프가 발생하는 것에 지쳐서 MySQL을 계속 사용하고 싶지 않습니다.

나는 네가 수백 줄의 데이터와 어쩌면 10 개의 키 이상으로 이것을 결코하지 않을 것이므로 중첩 루프 성능에 대해 걱정할 것입니다.

그러나 내장 된 PHP 함수를 사용하여이 작업을 수행 할 수있는 방법이 있는지 알고 싶습니다.
$keys_to_copy 배열에 키가 아닌 배열 값으로 배열되어 있기 때문에 array_intesect_key()을 보았습니다.

누구나 아이디어가 있습니까?

건배, B

+1

왜 '$ keys_to_copy'를 메인 루프로 사용하지 않습니까? – Yoshi

답변

28

나는 그것을 밖으로 일 - 나는 거의가 above.I 내가 완벽 어쨌든 답을 게시 할 거라고 생각했다. 희망이 사람을 도와줍니다!

array_intersect_key($data, array_flip($keys_to_copy))

사용 array_flip()

$keys_to_copy이 때문에이 대답에, 나는 위의 수동 루프 사이의 성능을 비교하기 위해 몇 가지 검사를 실행하겠습니다 array_intersect_keys()

내에서 사용할 수 있습니다 전환합니다. 나는 built-in 함수가 더 빠를 것이라고 기대할 것이다. 그러나 그들은 꽤 평등 할 것이다. 배열이 많이 최적화되어 있으므로 가까이있을 것이라고 확신합니다.

편집 : 나는 위의 내 대답에 코드 내 질문에 foreach() 코드를 비교하는 PHP CLI를 사용하여 일부 벤치 마크를 실행 한
. 결과는 아주 놀랍습니다.

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

그래서 많은 것
여기가 유효 생각 나는 벤치 마크에 사용 된 코드입니다 foreach보다는 PHP 배열 함수를 사용하는 배열 요소의로드가 빠릅니다. 나는 그것이 더 빠를 것이라고 생각했지만 그렇게 많이는 아니 었습니다!

+7

그게 바로 목적입니다. 다른 사람들을 도우려는 것입니다. 자신의 질문에 답을해도 이것이 올바른 방법입니다. – JYelton

+1

작업 순서를 뒤집어 쓰면 'foreach'가 빨라집니다. 'foreach ($ keys_to_copy AS $ 키) {$ copied_data [$ key] = $ data [$ key];}' –

0

전체 결과 집합을 배열로로드 한 다음 중첩 루프로 처리하기 시작하지 않겠습니까?

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