tags:

views:

28

answers:

2

I've got an array that uses UNIX timestamps for array keys. The array will typically hold data for anywhere from 15 minutes to maybe an hours worth of time, however there are only entries for seconds that have data.

Most of the data will be spread out, there will be occasional spans of data for consecutive seconds though. What I'd like to do, is retrieve the first and last second of the longest consecutive span of seconds in the array.

If I have this array

Array
(
    [1276033307] => 119.0
    [1276033331] => 281.8
    [1276033425] => 28.2
    [1276033431] => 88.2
    [1276033432] => 196.2
    [1276034207] => 205.5
    [1276034226] => 73.8
    [1276034227] => 75.8
    [1276034228] => 77.8
    [1276034230] => 79.8
)

I would either need the keys 1276034226 and 1276034228, or the following array returned.

Array
(
    [1276034226] => 73.8
    [1276034227] => 75.8
    [1276034228] => 77.8
)
+2  A: 

EDIT:

$array = array(
    1276033307 => 119.0,
    1276033331 => 281.8,
    1276033425 => 28.2,
    1276033431 => 88.2,
    1276033432 => 196.2,
    1276034207 => 205.5,
    1276034226 => 73.8,
    1276034227 => 75.8,
    1276034228 => 77.8,
    1276034230 => 79.8,
);

$finalArray = array();
foreach($array as $k => $v){
    $tempArrays = array();
    $index = 0;
    while(isset($array[$k + $index])){
        $tempArrays[$k+$index] = $array[$k+$index++];
    }

    if(count($tempArrays) > count($finalArray))
        $finalArray = $tempArrays;
}

print_r($finalArray);

the output is the same...

ORIGINAL:

Note: Only the first occurrence of the longest span will be recorded.

$array = array(
    1276033307 => 119.0,
    1276033331 => 281.8,
    1276033425 => 28.2,
    1276033431 => 88.2,
    1276033432 => 196.2,
    1276034207 => 205.5,
    1276034226 => 73.8,
    1276034227 => 75.8,
    1276034228 => 77.8,
    1276034230 => 79.8,
);

$longspan = 0;
foreach($array as $k => $v){
    $index   = 1;
    while(isset($array[$k+$index])){
        $index++;
    }

    $curspan = --$index;

    if($curspan > $longspan){
        $longspan = $curspan;
        $start    = $k;
    }
}

for($i=0; $i <= $longspan; $i++)
    $results[$start + $i] = $array[$start + $i];

print_r($results);

Outputs:

Array ( 
  [1276034226] => 73.8 
  [1276034227] => 75.8 
  [1276034228] => 77.8
) 
acmatos
if you modify your answer a bit and use an array to hold the values inside the isset (something like while(isset($array[$k+$index])){ $tempArr[$counter][] = $array[$k+$index]; }) and then check the lengths of the sub-arrays, i think you can do a lot more. Let me know if it feels cryptic. Feeling too lazy..
pinaki
ofcourse you would need to define and use a $counter....
pinaki
thanks pinaki ;) edited accordingly i think... not sure if i got it right :-p if not, at least you made me look at it from other perspective. :-)
acmatos
almost there. The thing i was pointing to was your comment that it would display only the first occurence. My bad, was a horrible explanation ;). My idea was to create an array of array (the $tempArr) and once you have the array, you can do a count on the sub-arrays to decide which is/are the longest.
pinaki
+1  A: 

This code does it in a single loop (i.e. is a Greedy algorithm):

$array = array(
    1276033307 => 119.0,
    1276033331 => 281.8,
    1276033425 => 28.2,
    1276033431 => 88.2,
    1276033432 => 196.2,
    1276034207 => 205.5,
    1276034226 => 73.8,
    1276034227 => 75.8,
    1276034228 => 77.8,
    1276034230 => 79.8,
);

$long_arr = array();
$curr_arr = array();
$last_key = -1;

foreach($array as $k => $v) {
    if ($k != $last_key + 1) {
        $curr_arr = array();
    }
    $curr_arr[$k] = $v;
    if (count($curr_arr) > count($long_arr)) {
        $long_arr = $curr_arr;
    }
    $last_key = $k;
}

print_r($long_arr);
Lukman