Флаг 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"?
Ответы
Ответ 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
выполняет сравнение типов.