Reputation: 17894
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.
Upvotes: 5
Views: 2279
Reputation: 48031
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,
)
Upvotes: 0
Reputation: 35146
$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];
}
}
Upvotes: 1
Reputation: 9402
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
Upvotes: 0
Reputation: 67745
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);
}
}
Upvotes: 2