PHP ксорт неожиданное поведение

Позвольте мне сказать вам с самого начала: я знаю о флагах сортировки этой функции. Когда я использую SORT_STRING это работает хорошо, но флаг по умолчанию SORT_REGULAR работает странно, или не работает вообще.

Рассмотрим массив, как показано ниже.

$arr = [
    '27a'   => 'foo',
    '27b'   => 'foo',
    '27c'   => 'foo',
    '27'    => 'foo',
];

Когда я пытаюсь сортировать, используя ksort, он дает массив без сортировки в какой-либо очевидной логике.

ksort($arr);

print_r($arr);

// this prints
Array
(
    [27a] => foo
    [27] => foo
    [27b] => foo
    [27c] => foo
)

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

$arr = [
    '27a'   => 'foo',
    '27'    => 'foo',
    '27b'   => 'foo',
    '27c'   => 'foo',
];

ksort($arr);

print_r($arr);

// this prints
Array
(
    [27b] => foo
    [27c] => foo
    [27] => foo
    [27a] => foo
)

Кто-нибудь знает логику этого? Это ошибка или я что-то упустил?

РЕДАКТИРОВАТЬ: Спасибо всем за интерес и ответили на мой вопрос. Хотя он помечен как дубликат, в другом вопросе не упоминалась более странная часть: почему изменение порядка исходного массива приводит к изменению результата? Он должен давать тот же результат с тем же набором входных данных. Должны ли мы обсудить это тоже?

1 ответ

Причина, по которой это происходит, заключается в том, что он видит ключи типа "27a" в виде строки и ключи типа "27" в виде целого числа, даже если оно заключено в кавычки. Вы увидите те же результаты, если уберете кавычки из клавиши 27.

И, как говорится на странице ksort: "Предупреждение: будьте осторожны при сортировке массивов со значениями смешанных типов, потому что sort() может привести к непредсказуемым результатам".

Конечно, странное поведение - к сожалению, лучший способ получить ожидаемые результаты, когда у вас есть ключи, которые выглядят как целые числа (даже если они являются строками), - это указать флаг сортировки, например, SORT_STRING, чтобы каждый раз получать ожидаемые результаты.

Другие вопросы по тегам