2014-03-19 2 views
0

두 키 사이에서 배열의 하위 배열을 가져 오는 가장 효율적인 방법은 무엇입니까? 2014년 2월 4일을 키 종료 : 그래서 예를 들어php 두 배열 키 사이에서 하위 배열 가져 오기

,

$arr=array(); 
$arr['2014-03-01']='something'; 
$arr['2014-03-03']='something'; 
$arr['2014-02-04']='something'; 
$arr['2014-03-05']='something'; 
$arr['2014-03-07']='something'; 
$arr['2014-03-09']='something'; 
$arr['2014-01-04']='something'; 
$arr['2014-03-31']='something'; 

두 개의 키 사이의 부분 배열을 가져 즉, 키 시작 2014년 3월 7일 만에 배열을 반환해야합니다

$arr['2014-02-04']='something'; 
$arr['2014-03-05']='something'; 
$arr['2014-03-07']='something'; 

배열을 통해을 반복하지 않고이 작업을 신속하고 효율적으로 수행 할 수 있습니까? ?

업데이트 :

$arr=array(); 
for ($i=1;$i<=1000000;$i++) { 
    $arr["$i"]=$i; 
} 

$time_start=microtime_float(); 

$start = '20000'; 
$end = '20010'; 

$offset = array_search($start, array_keys($arr)); 
$length = array_search($end, array_keys($arr)) - $offset + 1; 
$output = array_slice($arr, $offset, $length); 
print_r($output); 
$time_end = microtime_float(); 
$time = $time_end - $time_start; 
echo "TIME=$time\n"; 
echo "\n============\n"; 
$time_start=microtime_float(); 

$result = array(); 
$start = '20000'; 
$end = '20010'; 

foreach ($arr as $key => $value) { 
    if ($key >= $start && $key <= $end) 
    $result[$key] = $value; 
} 
print_r($output); 
$time_end = microtime_float(); 
$time = $time_end - $time_start; 
echo "TIME=$time\n"; 

exit; 

결과 :

Array 
(
    [0] => 20000 
    [1] => 20001 
    [2] => 20002 
    [3] => 20003 
    [4] => 20004 
    [5] => 20005 
    [6] => 20006 
    [7] => 20007 
    [8] => 20008 
    [9] => 20009 
    [10] => 20010 
) 
TIME=1.8481030464172 

============ 
Array 
(
    [0] => 20000 
    [1] => 20001 
    [2] => 20002 
    [3] => 20003 
    [4] => 20004 
    [5] => 20005 
    [6] => 20006 
    [7] => 20007 
    [8] => 20008 
    [9] => 20009 
    [10] => 20010 
) 
TIME=1.700336933136 

따라서, 간단한 루프가 약간 빠른 것 같다 나는 여기에 벤치 마크 한 결과입니다. 배열을 시작하면 더 많은 이점이 있습니다. 당신은 또한 휴식을 사용할 수 있습니다; 후자의 시점에 도달하면

+0

array_filter "각 값을 반복 해"그래서, 음, –

+0

음 선호하지 당신이 '각 가치에 대한 반복'문제를 피할 수있는 방법은 없습니다. – Achrome

+0

키는 위와 같이 정렬됩니다. –

답변

4

가장 효율적인 방법은 루프를 사용하는 것입니다.

$result = array(); 
$start = '2014-02-04'; 
$end = '2014-03-07'; 

foreach ($arr as $key => $value) { 
    // your date format is string comparable, otherwise use strtotime to convert to unix timestamp. 
    if ($key >= $start && $key <= $end) { 
    $result[$key] = $value; 
    } 
} 

또는 덜 효율적인 방법은 다음 결과를 얻을 수 array_intersect_key를 사용 후, 필요한 키에 array_filter를 사용하여 키와 값을 교환 할 array_flip을 사용하고 있습니다.

+0

거대한 배열을 사용합니다. 어쨌든 루핑하지 않고 이것을 할 수 있을까요? –

+0

@ 레이 루프없이 배열로 작업 할 수 없습니다. – deceze

+0

@xdazz 키가 비교되고 정렬되어있는 한 작동합니다. 반드시 일반적인 솔루션 일 필요는 없습니다. – deceze

2

당신은 ksort, array_slicearray_search로 시도 할 수 있습니다 :

$start = '2014-02-04'; 
$end = '2014-03-07'; 

ksort($arr); 
$offset = array_search($start, array_keys($arr)); 
$length = array_search($end, array_keys($arr)) - $offset + 1; 
$output = array_slice($arr, $offset, $length); 

var_dump($output); 

출력 : 키가 정렬되지 않는

array (size=5) 
    '2014-02-04' => string 'something' (length=9) 
    '2014-03-01' => string 'something' (length=9) 
    '2014-03-03' => string 'something' (length=9) 
    '2014-03-05' => string 'something' (length=9) 
    '2014-03-07' => string 'something' (length=9) 
+0

이 솔루션은 배열이 정렬되어 있다고 가정합니다. :) – Achrome

+0

@Achrome입니다. ''ksort'를보세요. – hsz

+0

나는 ksort를 알고있다.나는 그것이 단순한 루프 구조보다 느리다는 것을 의심한다. – Achrome