Подтвердить что ты не робот

Флаг Array_unique SORT_REGULAR

$array = array(1, '1a', '1');
var_export(array_unique($array, SORT_REGULAR));
  • Результат: array (0 = > 1, 2 = > '1')
  • В руководстве по PHP: SORT_REGULAR - обычно сравнивайте элементы (не меняйте типы).

Какова логика этого? Почему или как исключается "1a"?

4b9b3361

Ответ 1

Это происходит потому, что array_unique работает сначала сортируя значения как строки, затем итерации поверх отсортированный массив и для каждого значения, исключая из результата все последующие значения, сравнимые с ним.

Функция сравнения для "сравнения равных" выше выбирается в соответствии со вторым параметром, который для SORT_REGULAR совпадает с проверкой равенства с ==.

Такое поведение приводит к большому количеству ошибок. Поскольку сортировка является быстрой сортировкой, она нестабильна. Поэтому сортировка массива, содержащего как 1, так и '1', не дает гарантии, что в итоге результат окажется первым. Это означает, что array_unique может показаться произвольно "предпочтительным" 1 в некоторых случаях и '1' в других.

Однако безумие продолжается: считайте, что если сортировка выражает [1, '1', '1a'], то '1a' не будет включен в результат (он сравнивается с 1), а если сортировка выражает ['1', 1, '1a'], тогда он будет включен (он не сравнивается с строкой '1')!

Ответ 2

Если вы хотите получить немного больше технических средств, вы можете увидеть источник.

Флаг PHP_SORT_REGULAR просто сообщает array_unique вернуться к стандартному оператору сравнения (==).

Вы можете увидеть это в источнике array_unique, в котором используется php_set_compare_func:

static void php_set_compare_func(int sort_type TSRMLS_DC) /* {{{ */
{
switch (sort_type & ~PHP_SORT_FLAG_CASE) {
...
    case PHP_SORT_REGULAR:
    default:
        ARRAYG(compare_func) = compare_function;
        break;
} 

Где compare_func - это просто стандартная функция сравнения.

Вероятно, это ошибка документации больше, чем что-либо еще. Комментарий в документации немного вводит в заблуждение:

... равно тогда и только тогда, когда (string) $elem1 === (string) $elem2

Если оба значения передаются в строки, то === не требуется, но это приводит к предположению, что SORT_REGULAR выполняет сравнение типов.