2.72 [1] => 3.14 [2] => img1 [3] => img10 "> 2.72 [1] => 3.14 [2] => img1 [3] => img10 "> 2.72 [1] => 3.14 [2] => img1 [3] => img10 " />

Понимание порядка сортировки массива php

У меня этот массив

$array = array(2, 1, "img1", "img2", "img10", 1.5, "3.14", "2.72");

после применения функции sort она становится

sort($array);

Array
(
    [0] => 2.72
    [1] => 3.14
    [2] => img1
    [3] => img10
    [4] => img2
    [5] => 1
    [6] => 1.5
    [7] => 2
)

Я не понял, как выполняется сортировка.

Может ли кто-нибудь объяснить, как достигается выходной массив?

РЕДАКТИРОВАТЬ:

Здесь вопрос заключается не в том, какой SORT FLAG использовать, но вопрос в том, как выполняется вышеуказанная сортировка. Любой совет по использованию другого SORT FLAG бесполезен здесь.

5
nl ja de
Установите флаг SORT_NUMERIC php.net/sort .
добавлено автор Pekka 웃, источник
@Pekka 웃: Я действительно хочу знать, как сортировка выполняется даже с помощью SORT_REGULAR . Что означает SORT_REGULAR? Как сортировать регулярные приоритеты назначения для элементов в результате сортировки?
добавлено автор Daric, источник
Так что я почти уверен, что понял ответ на этот вопрос. Я отправлю его позже сегодня вечером, когда вернусь домой (если кто-то не ударит меня).
добавлено автор Scott, источник

3 ответы

Первые два числа были действительными строками (вы передавали их в кавычки), поэтому их обрабатывают так: цифры поступают до буквы в алфавитном порядке.

Другие были действительными числами (без кавычек), поэтому функция помещала их отдельно, сортируя их численно.

array(8)
    0 => '2.72'    [alphabetical]
    1 => '3.14'    [alphabetical]
    2 => 'img1'    [alphabetical]
    3 => 'img10'   [alphabetical]
    4 => 'img2'    [alphabetical]
    5 => 1         [numeric]
    6 => 1.5       [numeric]
    7 => 2         [numeric]

Таким образом, функция должна решить, будет ли он сортировать элементы по алфавиту (a, b, c ...) или численно (1,2,3 ..), поэтому он просто проверяет тип переменной.

Как указывал Пекка, есть флаги, которые можно задать, чтобы заставить тип сортировки. Они описаны в документах .


РЕДАКТИРОВАТЬ

Эта теория оказалась ошибочной в комментариях, и я полностью потерялся сейчас (:

This comment at the docs contains some interesting points on this issue.

6
добавлено
то, что я пытаюсь сказать, заключается в том, что он использует BOTH числовую и алфавитную сортировку, в зависимости от типов, которые вы передавали в качестве аргумента. Числа начинаются сначала в алфавитном порядке сортировки, но сама сортировка по алфавиту начинается до численной сортировки.
добавлено автор hugo_leonardo, источник
Вау! хорошо, я полностью потерял сейчас D:
добавлено автор hugo_leonardo, источник
хорошо, если даже механизм кеша может помешать порядку, я думаю, можно с уверенностью сказать, что он «непредсказуем», когда вы смешиваете типы.
добавлено автор hugo_leonardo, источник
Можете ли вы расширить свой ответ? Я действительно не получаю, это будет большой помощью, если вы сможете объяснить дальше.
добавлено автор Daric, источник
И я тоже сейчас очень сильно смущен алгоритмом сортировки со смешанным типизированным массивом и пытается использовать различные флаги сортировки для этого типа массива. На самом деле нужно получить фактический алгоритм сортировки со всеми флажками сортировки. Надеюсь, кто-то вернется с тем же
добавлено автор Daric, источник
Это не отвечает, какой алгоритм сравнения используется на бэкэнде, и для меня это вопрос. В ожидаемом результате числа будут поступать до строк. Это касается почти всех видов, которые вы обнаружите, особенно из-за значений ascii. Почему PHP выполняет число, чтобы сортировать второй? Я проверил документацию и выполнил некоторые тесты, функции сортировки не используют стандартные операторы (==, <,>), strcmp (), ord (). Кто-нибудь знает, что он использует при реализации sort() без флагов?
добавлено автор Scott, источник
Позвольте мне показать вам, что вы ошибаетесь, посмотрите на ссылку @coanda. Если у вас есть шанс сортировать этот массив: («a», «b», «4», 5,4, «true», «TRUE», true, false, «c», «d»). Затем сортируйте этот массив: («a», «b», «4», 5,4, «true», «TRUE», true, false, «c»). Они возвращают 2 совершенно разные результаты, просто удаляя элемент «d». Согласно PHP это не ошибка, а результат жонглирования типа.
добавлено автор Scott, источник

Используя информацию в ссылке для Coanda в качестве отправной точки, ясно, что PHP использует манипуляцию типа при сравнении объектов разных типов. Проблема заключается в понимании того, что бросается во время сравнения, и я до сих пор не смог найти полный список, но в целом:

строка по сравнению с int превратится в

(int) string <,>,=, (int) int 

В этом случае строка после литья становится 0, поэтому все ints больше строки. (Ожидается). Это единственный случай, о котором нам нужно беспокоиться об этом.

PHP использует quicksort и, скорее всего, выбирает свою опорную точку как array [n/2] , где n - числовые элементы в массиве. Зная эти две части информации, мы быстро сортируем вышеупомянутый массив:

$pivot = $array[n/2] //n is the number of elements, this sets $pivot='img2'
//compare each element in the list (i am going to this by hand for demonstration)

(int) 'img2' < 2 //int to int comparison;'img2' resolves to 0 and 0 < 2
(int) 'img2' < 1 //int to int comparison;'img2' resolves to 0 and 0 < 1
      'img2' > 'img1'//string to string comparison; strcmp is +256 
      'img2' > 'img 10' //string to string comparison; strcmp is +256 
(float) 'img2' < 1.5 //float to float comparison;'img2' resolves to 0 and 0<1.5 
      'img2' > '3.14' //string to string comparison; strcmp is +54
      'img2' > '2.72' //string to string comparison; strcmp is +55

Теперь у нас есть два новых массива (один для большего и один для меньшего).

 $greater = array('img1', 'img10', '3.14', '2.72);
 $less = array(2, 1, 1.5);

Теперь нет необходимости вдаваться в подробности, поскольку мы случайно создали 2 массива, в которых есть все легко сопоставимые объекты. $ large имеет только строки, и мы можем предположить, что сортировка будет нормально работать здесь и рассматривать все строки.

sort($greater);
var_dump($greater);

производит

array(4) {
  [0]=>
  string(5) "2.72"
  [1]=>
  string(4) "3.14"
  [2]=>
  string(4) "img1"
  [3]=>
  string(5) "img10"
}

This is what we expected and also the result above. We do the same with $lesser

$lesser = array(2, 1, 1.5);
sort($lesser);
var_dump($lesser);

мы получаем

array(3) {
  [0]=>
  int(1)
  [1]=>
  float(1.5)
  [2]=>
  int(2)
}

Which is also expected. Now when we concat all three arrays together (for the sake of recursiveness I am calling 'img2' an array). мы получаемthe results above.

Array
(
[0] => 2.72
[1] => 3.14
[2] => img1
[3] => img10
[4] => img2
[5] => 1
[6] => 1.5
[7] => 2
)

Чтобы доказать это, вы можете выполнить один и тот же процесс для этого же массива, но отключите $ arr [3] с целым числом.

$arr = array("img2", 1, "img1", 2, "img10", 1.5, "3.14", "2.72");
sort($arr);
var_dump($arr)

дает вам совершенно другой результат, потому что стержень изменился с строки на int, заставляя строки float оцениваться как float.

array(8) {
[0]=>
string(4) "img1"
[1]=>
string(5) "img10"
[2]=>
string(4) "img2"
[3]=>
int(1)
[4]=>
float(1.5)
[5]=>
int(2)
[6]=>
string(4) "2.72"
[7]=>
string(4) "3.14"
}
3
добавлено
Спасибо за ваши исследования
добавлено автор Daric, источник

The following bug gives more insight in sorting mixed types: https://bugs.php.net/bug.php?id=21728

Цитата:

<?php
$arr1 = array("a","b","c","d","4",5,4,"true","TRUE",true);
sort($arr1);
var_dump($arr1);
?>

The output is :
array(10) {
  [0]=>
  bool(true)
  [1]=>
  int(4)
  [2]=>
  string(1) "4"
  [3]=>
  string(4) "TRUE"
  [4]=>
  string(1) "a"
  [5]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
  [8]=>
  string(4) "true"
  [9]=>
  int(5)
}

Это может показаться странным - почему (int) 5 - это все строки. Это происходит потому, что «4» меньше, чем (int) 5, «4» перед «истинным» и «истинным» является   до 5. Первые 2 очевидны, третий - нет. Но это нормально.   Лучше не смешивать типы в массиве. Если 5 изменено на «5», тогда   «5» идет сразу после «4».

1
добавлено
Я пишу свои собственные функции сортировки, когда у меня смешанные типы. Функция usort проста и эффективна в использовании. См. Ссылку . Я думаю, что очень сложно предсказать результат собственной функции сортировки PHP.
добавлено автор Coanda, источник
phpGeeks
phpGeeks
3 620 участник(ов)

Best PHP chat Еще: @dbGeeks - базы данных @phpGeeksJunior - новичкам @moscowProgers - IT Москва @ebanoePhp - весёлый канал о PHP @laravel_pro - Laravel @jobGeeks - вакансии @jsChat - JS Правила: https://t.me/phpGeeks/764859 ДР - 28.03.2016

PHP
PHP
1 309 участник(ов)

Группа про современный PHP. Обсуждаем ООП, TDD, BDD, DDD, SOLID, GRASP и прочие крутые базворды Для ознакомления: https://gist.github.com/mkusher/711bd46f0b62fbae851182e6fb3b1839 Группа PHP для новичков @phpGeeksJunior Вакансии: https://t.me/fordev

PHP — вакансии, поиск работы и аналитика
PHP — вакансии, поиск работы и аналитика
1 251 участник(ов)

Публикуем вакансии и запросы на поиск работы по направлению PHP, Laravel, Symfony, Yii и т.д. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @qa_jobs, @devops_jobs, @javascript_jobs, @nodejs_jobs, @uiux_jobs, @products_jobs

phpGeeksJunior
phpGeeksJunior
980 участник(ов)

Группа для новичков. Не стесняйтесь задавать вопросы по php. Не флудить!!!! Правила и полезные ссылки https://gist.github.com/exileed/a53dd0617b35a705ff44b38c8028e6a5 Бест от пхпгикс https://t.me/best_of_phpgeeks

phpclub.ru
phpclub.ru
872 участник(ов)

Официальный чат phpclub.ru - остерегайтесь подделок #rules Правила группы - уважайте друг друга. Скриншоты -> ссылками. Код -> pastebin.com. Вакансии строго -> https://goo.gl/4bNxym, в чат ссылку. За рекламу и мат - БАН!

Devall | PHP
Devall | PHP
272 участник(ов)

Пристанище для восходящих звёзд разработки, которые перейдут на более адекватные языки. http://combot.org/chat/-1001014863761 Инвайт: j.mp/devallphp