2

I need to check an array for its keys. If they are consecutive, its good,if not i need to fill in some data.

e.g.

Array
(
    [0] => 0
    [1] => 1
    [2] => 8
    [3] => 0
    [4] => 0
    [5] => 0
    [6] => 0
    [7] => 0
    [8] => 0
    [10] => 0
    [11] => 0
    [12] => 0
    [14] => 0
    [15] => 0
)

In this case, the indexes 9 and 13 are missing. To make the example easier, I just want to fill the missing data with the number 999.

My solution however is a little sloppy and doesn't work properly:

$oldK = 0;
foreach($array as $k=>$entry)
{   
    if($oldK !== $k)
    {
        $array[$oldK] = 999;
    }

    $oldK ++;
}

produces following output:

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

is there a smooth way that works?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
toffler
  • 1,231
  • 10
  • 27

4 Answers4

3

You may use array_replace combined with array_fill:

$keys = array_keys($a);
$result = array_replace(array_fill(0, max($keys), 999), $a);

Grabbing keys through array_keys first should make it work for any number of elements (provided the keys are numeric, obviously).

Demo: https://3v4l.org/Ik71a

Jeto
  • 14,596
  • 2
  • 32
  • 46
  • Good point about the use of `min` and `max` function. You answer is simpler than mine – dWinder Feb 06 '20 at 13:23
  • Thanks, all answers works like expected --> but I like this one the most because its just in 1 line. +1 to every answer – toffler Feb 06 '20 at 13:25
  • 1
    Actually made a slight fix: the second argument to `array_fill` should be `max($keys) - min($keys)` to make it work in every case. – Jeto Feb 06 '20 at 13:30
  • @toffler Can you confirm if you want the key to start from `0` or `2` itself [in this case](https://3v4l.org/l9hRh)? – nice_dev Feb 06 '20 at 13:34
  • I am late @Jeto nice solution –  Feb 06 '20 at 13:36
  • 1
    @vivek_23 good point! In my case the array always starts from `0`, therefore this solution fits but in other cases your's might be better. – toffler Feb 06 '20 at 13:38
  • 1
    @toffler This answer will fit too. Just replace all `min($keys)` to `0` in this solution. – nice_dev Feb 06 '20 at 13:39
  • @AnantSingh---AlivetoDie Yes, that was in case indices didn't start at 0 (e.g. https://3v4l.org/AOHq2 -- would go over 15 if I didn't substract the min index). But since then OP has mentioned always start from 0, so I just edited the post again. – Jeto Feb 07 '20 at 07:42
  • @Jeto I would rollback answer to second edit! it was fine `array_replace(array_fill(min($keys), max($keys), 999), $a)` without specifying 0. min starts with the minimum key which is -> 0. replacing min with 0, wont display the result. demo new https://3v4l.org/YJ3Wv –  Feb 07 '20 at 08:33
  • @Dlk It will display the result if you print it ;) I just thought it wasn't necessary to use `min` if you know for a fact the array will start at 0, as OP mentioned in an earlier comment. In which case it's a very minor optimization. In any case, (s)he can read this comment thread and pick whichever solution fits him/her best. – Jeto Feb 07 '20 at 09:30
  • @Jeto opps my bad :) :) –  Feb 07 '20 at 09:36
2

You can use array-fill to create you array and then fill (override) with data from the original array:

$keys = array_keys($arr);
$new = array_fill(min($keys), max($keys),999);
foreach($new as $k => &$v)
    if (isset($arr[$k])) $v = $arr[$k];

Notice the & to alter the value in the looping array

Another way to achieve that is with the + operator. Just use ksort afterward if you want the order:

$keys = array_keys($arr);
$new = $arr + array_fill(min($keys), max($keys),999);
ksort($new);

Live example 3v4l

dWinder
  • 11,597
  • 3
  • 24
  • 39
1
$oldK = 0;
foreach($array as $k=>$entry)
{   
    if($oldK !== $k)
    {
        $array[$oldK] = 999;
    }

    $oldK ++;
}

In your above code, you are advancing the array pointer $k without waiting for keys to fill in a sequential order. To compare $oldK !== $k, the $k needs to be still until $oldK reaches it. Below is the fixed code where in we loop over the keys of the array and do the checks.

$keys = array_keys($array);
$oldK = 0;
while(current($keys) !== false){
    $key = current($keys);
    if($key === $oldK) next($keys);
    else $array[$oldK] = 999;
    $oldK++;
}
ksort($array);// to arrange them in sorted order

Demo: https://3v4l.org/GD61j

nice_dev
  • 17,053
  • 2
  • 21
  • 35
0

This should be your complete solution

//4 and 5 is missing in given array1
$arr1 = [0 => 0, 1 => 0, 2 => 8, 3 => 0, 11 => 0, 12 => 0, 15 => 0];

//Create a new array
$arr2 = range(1,max($arr1));

// use array_diff to get the missing numbers and create a new array with them
$missingNumbers = array_diff($arr1,$arr2); 

$keys = array_keys($missingNumbers);
$Sonuc = array_replace(array_fill(min($keys), max($keys), 999), $arr1);
print_r($Sonuc);

Demo : https://3v4l.org/TbAho