Tutorial :PHP loops to check that a set of numbers are consecutive



Question:

I'm trying to loop through a set of records, all of which have a "number" property. I am trying to check if there are 3 consecutive records, e.g 6, 7 and 8.

I think i'm almost there with the code below, have hit the wall though at the last stage - any help would be great!

$nums = array();  while (count($nums <= 3))  {      //run through entries (already in descending order by 'number'      foreach ($entries as $e)      {          //ignore if the number is already in the array, as duplicate numbers may exist          if (in_array($e->number, $num))              continue;          else          {              //store this number in the array              $num[] = $e->number;          }      //here i need to somehow check that the numbers stored are consecutive      }  }  


Solution:1

function isConsecutive($array) {      return ((int)max($array)-(int)min($array) == (count($array)-1));  }  

You can achieve the same result without looping, too.


Solution:2

If they just have to be consecutive, store a $last, and check to make sure $current == $last + 1.

If you're looking for n numbers that are consecutive, use the same, except also keep a counter of how many ones fulfilled that requirement.


Solution:3

$arr = Array(1,2,3,4,5,6,7,343,6543,234,23432,100,101,102,103,200,201,202,203,204);    for($i=0;$i<sizeof($arr);$i++)  {       if(isset($arr[$i+1]))      if($arr[$i]+1==$arr[$i+1])      {            if(isset($arr[$i+2]))          if($arr[$i]+2==$arr[$i+2])           {                if(isset($arr[$i+3]))                     if($arr[$i]+3==$arr[$i+3])              {                   echo 'I found it:',$arr[$i],'|',$arr[$i+1],'|',$arr[$i+2],'|',$arr[$i+3],'<br>';               }//if3            }//if 2        }//if 1  }  

I haven't investigated it thoroughly, maybe can be improved to work faster!


Solution:4

Here's an example that can check this requirement for a list of any size:

class MockNumber  {      public $number;      public function __construct($number)      {          $this->number = $number;      }        static public function IsListConsecutive(array $list)      {          $result = true;          foreach($list as $n)          {              if (isset($n_minus_one) && $n->number !== $n_minus_one->number + 1)              {                  $result = false;                  break;              }                $n_minus_one = $n;          }            return $result;      }  }    $list_consecutive = array(       new MockNumber(0)      ,new MockNumber(1)      ,new MockNumber(2)      ,new MockNumber(3)  );    $list_not_consecutive = array(       new MockNumber(5)      ,new MockNumber(1)      ,new MockNumber(3)      ,new MockNumber(2)  );    printf("list_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_consecutive) ? 'is' : 'is not');  // output: list_consecutive is consecutive    printf("list_not_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_not_consecutive) ? 'is' : 'is not');  // output: list_not_consecutive is not consecutive  


Solution:5

If u don't wanna mess with any sorting, picking any of three numbers that are consecutive should give you: - it either is adjacent to both the other numbers (diff1 = 1, diff2 = -1) - the only number that is adjacent (diff = +-1) should comply the previous statement.

Test for the first condition. If it fails, test for the second one and under success, you've got your secuence; else the set doesn't comply.

Seems right to me. Hope it helps.


Solution:6

I think you need something like the following function (no need of arrays to store data)

<?php  function seqOfthree($entries) {  // entries has to be sorted descending on $e->number    $sequence = 0;    $lastNumber = 0;      foreach($entries as $e) {      if ($sequence==0 or ($e->number==$lastNumber-1)) {        $sequence--;      } else {        $sequence=1;      }      $lastNumber = $e->number;      if ($sequence ==3) {        // if you need the array of sequence you can obtain it easy        // return $records = range($lastNumber,$lastNumber+2);        return true;      }    }    // there isn't a sequence    return false;  }  


Solution:7

function isConsecutive($array, $total_consecutive = 3, $consecutive_count = 1, $offset = 0) {      // if you run out of space, e.g. not enough array values left to full fill the required # of consecutive count      if ( $offset + ($total_consecutive - $consecutive_count ) > count($array) ) {          return false;      }        if ( $array[$offset] + 1 == $array[$offset + 1]) {          $consecutive_count+=1;          if ( $consecutive_count == $total_consecutive ) {              return true;          }          return isConsecutive($array, $total_consecutive, $consecutive_count, $offset+=1 );      } else {          return isConsecutive($array, $total_consecutive, 1, $offset+=1 );      }  }  


Solution:8

The following function will return the index of the first of the consecutive elements, and false if none exist:

function findConsecutive(array $numbers)  {      for ($i = 0, $max = count($numbers) - 2; $i < $max; ++$i)          if ($numbers[$i] == $numbers[$i + 1] - 1 && $numbers[$i] == $numbers[$i + 2] - 2)              return $i;      return false;  }  

Edit: This seemed to cause some confusion. Like strpos(), this function returns the position of the elements if any such exists. The position may be 0, which can evaluate to false. If you just need to see if they exist, then you can replace return $i; with return true;. You can also easily make it return the actual elements if you need to.

Edit 2: Fixed to actually find consecutive numbers.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »