I have an array like this:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 10
    [4] => 11
    [5] => 12
    [6] => 13
    [7] => 14
    [8] => 23
    [9] => 24
    [10] => 25
)

And I want to fill the gaps so it looks like this:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => xxx
    [4] => 10
    [5] => 11
    [6] => 12
    [7] => 13
    [8] => 14
    [9] => xxx
    [10] => 23
    [11] => 24
    [12] => 25
)

If you look at the values of the first array, there is 1,2,3 and then a gap and then 10,11,12,13,14 and then a gap and then 23,24,25. How can I programmatically find these gaps and add a new array element in its place?

There will be a maximum of two gaps.

4

There are 4 answers

0
netcoder On BEST ANSWER

A simple for loop, without copying the array, but only altering the original:

$repl = 'xxx';

for ($i=1; $i<count($array); $i++) {
    $valueR = $array[$i];
    $valueL = $array[$i-1] === $repl ? $array[$i-2] : $array[$i-1];
    if ($valueR > $valueL + 1) {
        array_splice($array, $i++, 0, $repl);
    }
}
3
Shai Mishali On

I would do something like this, not tested but should work :)

$oldArray = array(1,2,3,10,11,12,13,24,25,26,27);

$newArray = array();
for($i=0;$i<count($oldArray);$i++){
    $newArray[] = $oldArray[$i];
    if($oldArray[$i+1] - $oldArray[$i] != 1 && $i+1 != count($oldArray))
        $newArray[] = "xxx"; // seperator
}

var_dump($newArray);

Shai

4
Muhammad Hasan Khan On
$result = array();
if (count($oldArray) > 0)
{
    $result[] = $oldArray[0];
    for ($i=1; $i<count($oldArray); $i++)
    {
         if ($oldArray[$i]-$oldArray[$i-1] != 1)
             $result[] =  "xxx";
         $result[] = $oldArray[$i];
    }
}
0
mickmackusa On

Rather than doubling the memory by populating a new, extended array, I'll modify the input array (as @netcoder did).

foreach() is unsuitable to use with array_splice() because will foul up the indexes while you iterate.

For stability, use a for() loop. To minimize calls of count(), only call it once at the start of the loop, then bump the cached count only when necessary.

Because the first element will never qualify for the injection of the new element, start the loop at index 1.

If the the previous element's value + 1 is equal to the current element's value, then inject the element at that position into the original array. After the injection, bump the $i and $count variables so that the loop performs an additional iteration, but doesn't bother visiting the injected element.

Code: (Demo)

$array = [-5, 1, 2, 3, 10, 11, 12, 13, 14, 23, 24, 25, 31];
for ($i = 1, $count = count($array); $i < $count; ++$i) {
    if (($array[$i - 1] + 1) != $array[$i]) {
        array_splice($array, $i++, 0, 'xxx');
        ++$count;
    }
}
var_export($array);

Output:

array (
  0 => -5,
  1 => 'xxx',
  2 => 1,
  3 => 2,
  4 => 3,
  5 => 'xxx',
  6 => 10,
  7 => 11,
  8 => 12,
  9 => 13,
  10 => 14,
  11 => 'xxx',
  12 => 23,
  13 => 24,
  14 => 25,
  15 => 'xxx',
  16 => 31,
)