phparraysfilteroctalarray-difference

Incorrect output using array_diff() when integer values are left padded with zeros


The following code works fine with the supplied array.

$arr1 = array(1,2,4,6,7,9,13,15); 

$arr2 = range(1,max($arr1));                                                    

$missing = array_diff($arr2,$arr1); 

foreach ($missing as $key => $val) {
    echo $val;
    echo ",";
}

But if I change $arr1 to contain 001,002,004,006,007,009,013,015, it gives this output: 003,005,008,009,010,012,

I format the output by putting this in the foreach loop:

$val = str_pad($val, 3, "0", STR_PAD_LEFT); 

I cannot figure out why it declares 009 to be missing; why it doesn't declare 011 and 014 to be missing; and why it concludes with a comma.

Is there a way to rewrite the code so it processes the array correctly?


Solution

  • This is because numbers starting with 0 are octal numbers:

    http://php.net/manual/pl/language.types.integer.php

    To solve this you may store your values in the original array as strings:

    $arr = ['001', '002', '005', '011', '007'];
    

    then

    echo max($arr); //011
    

    still finds the right one, so now just:

    for ($i=1; $i<=ltrim(max($arr), '0'); $i++) {
        $newArr[] = str_pad($i, 3, '0', STR_PAD_LEFT);
    }
    

    And then the diff is OK:

    print_r(array_diff($newArr, $arr));
    Array
    (
        [2] => 003
        [3] => 004
        [5] => 006
        [7] => 008
        [8] => 009
        [9] => 010
    )
    

    TESTED ON PHP7

    Reference: