Некорректный вывод с использованием array_diff

#php

#php

Вопрос:

Следующий код отлично работает с предоставленным массивом.

 $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 ",";
}
  

Но если я изменю $arr1, чтобы он содержал 001,002,004,006,007,009,013,015, это даст такой результат: 003,005,008,009,010,012,

Я форматирую вывод, помещая это в цикл foreach:

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

Я не могу понять, почему он объявляет 009 отсутствующим; почему он не объявляет 011 и 014 отсутствующими; и почему он заканчивается запятой.

Есть ли способ переписать код, чтобы он правильно обрабатывал массив?

Комментарии:

1. Есть ли способ переписать код, чтобы он правильно обрабатывал массив?

Ответ №1:

Это потому, что числа, начинающиеся с 0, являются восьмеричными числами:

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

Чтобы решить эту проблему, вы можете сохранить свои значения в исходном массиве в виде строк:

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

затем

 echo max($arr); //011
  

все еще находит правильный, так что теперь просто:

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

И тогда разница в порядке:

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

ПРОВЕРЕНО НА PHP7

Ссылка:

Комментарии:

1. Я пытался использовать метки ‘ ‘ вокруг значений, но это не сработало. Я попробую это снова.

Ответ №2:

Ваши начальные нули сделали числа восьмеричными.

Комментарии:

1. Есть ли способ обрабатывать окталы?

2. Восьмеричные, десятичные, шестнадцатеричные и т.д. — это просто способы представления числа, точно такие же, как двоичные. Мы представляем шестнадцатеричные числа, помещая 0x спереди, и мы представляем восьмеричные числа, помещая ноль спереди. Итак, когда у вас есть значение 011 в вашем коде, вы явно объявляете значение, эквивалентное десятичному значению 9. Почему вы должны ставить начальные нули? Если вам это нужно для некоторых табличных результатов, я предлагаю добавить начальные нули в вывод строки, но оставить ввод как десятичный.

3. Начальные нули поступают из базы данных. Они являются частью номера экзамена, который имеет структуру ALPHA-ALPHA-NUMERIC-NUMERIC-NUMERIC-ALPHA-ALPHA

4. Так, например, GC005ABX. Кандидаты однозначно идентифицируются с 001 по 999; другая информация относится к экзаменационному центру, уровню и году. Я анализирую номера экзаменов и перебираю от 001 до 999 и генерирую корреспонденцию и сертификаты для каждого кандидата. Если кандидат вытаскивает — скажем, GC035ABX — я хочу иметь возможность обнаружить этот пробел в последовательности и исключить их из дальнейших действий. Последовательность из 1,2,3 …. 999 не будет ссылаться на фактические номера экзаменов в системе.

5. Если вы конвертируете из строки, рассмотрите возможность использования intval функции ( php.net/manual/en/function.intval.php ), который принимает базовое значение в качестве необязательного параметра. Значение по умолчанию равно 10, то есть десятичное, но не помешает указать это явно.