3

Sorry if the title of the question is unclear, I couldn't sum it up more precisely.

This is the issue:

To begin with, I have an array in this format:

Array ( 
    [0] => 09:00 
    [1] => 10:00 
    [2] => 11:00 
    [3] => 12:00 
    [4] => 13:00 
    [5] => 14:00 
    [6] => 15:00 
    [7] => 16:00 
    [8] => 17:00 
    [9] => 18:00 
) 

Then some of the members are unset, so after that we're left with something like:

Array ( 
    [0] => 09:00 
    [1] => 10:00 
    [6] => 15:00 
    [7] => 16:00 
    [8] => 17:00 
    [9] => 18:00 
) 

As you see, the array represents time slots. Now, what I need to do is eliminate all time slots shorter than 3 hours. So I need to go through the array and, wherever there are less than 3 members of the original array present, take them out too. So in the example above, since 09:00 and 10:00 are not followed by 11:00, I need to take them out and be left with:

Array ( 
    [6] => 15:00 
    [7] => 16:00 
    [8] => 17:00 
    [9] => 18:00 
)  

How do I accomplish this? Logically, I think it might be easiest to check for 3 consecutive indexes, rather then checking the actual times but I'm open to any suggestions.

3
  • 1
    But then, you've 15-16-17-18, but no 19, so, 17-18 will be removed too! Commented Apr 25, 2012 at 9:51
  • Well that was just an illustration, obviously that is not the logic I'd want to use (removing any two members with no third member following). I'd need to somehow check each element for either two previous elements, two following elements or one on each side - and only remove it if none of the three options are found. Commented Apr 25, 2012 at 9:53
  • 1
    Then you need to explain what logic you want to use. We just can guess Commented Apr 25, 2012 at 9:54

4 Answers 4

1

I've solved the problem on my own, and I made it generic so it would work for any duration, not just 3 hours.

$dur=3;  //could be anything
foreach($work_times as $member){
    $key=array_search($member,$work_times);
    $a_ok=0;
    for($options=0;$options<$dur;$options++){
        $thisone=1;
        for($try=$key-$options;$try<$key-$options+$dur;$try++){
            if(!array_key_exists($try,$work_times))
                $thisone=0;
        }
        if($thisone==1)
            $a_ok=1;
    }
    if($a_ok==0)
        unset($work_times[$key]);
}
Sign up to request clarification or add additional context in comments.

Comments

0
$arr = array(
  0 => '09:00',
  1 => '10:00',
  6 => '15:00',
  7 => '16:00',
  8 => '17:00',
  9 => '18:00'
);
// for some testing
$arr += array(12 => '19:00', 13 => '20:00', 14 => '21:00');
$arr += array(16 => '22:00', 17 => '23:00');


$dontRemove = array();

foreach($arr as $key => $val) {
  // if the next 2 keys are set
  if (isset($arr[$key+1]) && isset($arr[$key+2])) {
    $dontRemove[] = $key;
    $dontRemove[] = $key+1;
    $dontRemove[] = $key+2;
  }
}

// combine and diff the keys to get the keys which should be actually removed
$remove = array_diff(array_keys($arr), array_unique($dontRemove));

foreach($remove as $key) {
  unset($arr[$key]);
}

print_r($arr);

Comments

0

Try this:

<?php
function check() {
    global $array;

    $tmpArr = array_keys( $array );

    $val1 = $tmpArr[0];
    $val2 = $tmpArr[1];
    $val3 = $tmpArr[2];

    if( ( ++$val1 == $val2 ) && ( ++$val2 == $val3 ) ) {
        // continuous
    } else {
        // not continuous, remove it
        unset( $array[$tmpArr[0]] );
    }
}

$array = array( 
    '0' => '09:00', 
    '1'=> '10:00', 
    '6' => '15:00',
    '7'=> '16:00',
    '8' => '17:00',
    '9' => '18:00'
);

$total = count( $array );
$ctotal = 0;
while( $ctotal < $total ) {
    if( count( $array ) <= 2 ) {
        // this array has 2 elements left, which obviously
        // nullifies the 3 continuous element check
        $array = array();
        break;
    } else {
        //check the array backwards
        check();
        $total--;
    }
}
?>

Hope this helps

Comments

0
$a = Array(
    0 => "09:00",
    1 => "10:00",
    6 => "15:00",
    7 => "16:00",
    8 => "17:00",
    9 => "18:00",
    11 => "20:00",
);

foreach ($a as $k => $v) {
    // previous or next two time slots exist
    $consecutive = (isset($a[$k-1]) or
                    (isset($a[$k+1]) and isset($a[$k+2])));
    if (!$consecutive)
        unset($a[$k]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.