简体   繁体   中英

Check PHP array for consecutive indexes

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM