Почему usort работает не так как ожидаю?

Ссылка скопирована
PHP
1 ответ

Есть многомерный массив с данными вида:

Почему usort работает не так как ожидаю?

Для сортировки использую функцию, сначала сравниваю очки, если == иду смотреть на сумму:

usort($result, function($a, $b) {             if($a['data']['stats']['point'] == $b['data']['stats']['point']) {                 if($a['data']['stats']['sum'] == $b['data']['stats']['sum']) {                     return 0;                 }                  return ($a['data']['stats']['sum'] > $b['data']['stats']['sum']) ? -1 : 1;             }              return ($a['data']['stats']['point'] > $b['data']['stats']['point']) ? -1 : 1;         });

usort($result, function($a, $b) { if($a['data']['stats']['point'] == $b['data']['stats']['point']) { if($a['data']['stats']['sum'] == $b['data']['stats']['sum']) { return 0; } return ($a['data']['stats']['sum'] > $b['data']['stats']['sum']) ? -1 : 1; } return ($a['data']['stats']['point'] > $b['data']['stats']['point']) ? -1 : 1; });

Ожидаю, что при равных очках, будет сортировать по сумме, но как видим на скрине - нет. При этом, такой баг только с первыми элементами, дальше работает как нужно.

Дополнительно:

возможно, дело в том, что point содержит вещественное число. Для сравнения таких чисел используйте эпсилон:

const EPSILON = 0.0001; if ( abs( $a['data']['stats']['point'] -$b['data']['stats']['point'] ) < EPSILON ) ... // equals

const EPSILON = 0.0001; if ( abs( $a['data']['stats']['point'] -$b['data']['stats']['point'] ) < EPSILON ) ... // equals

Но по скриншоту, вроде всё ок: 329880 < 699093 , сортировка по возрастанию. Что Вас смутило?

  • Михаил Ливач, прикол в том, что на следующих элементах массива - все норм:

    Почему usort работает не так как ожидаю?

  • Михаил Ливач, но ваш совет помог! Спасибо! Почему не в ответе?) Напишите, отмечу лучшим
  • Попробуйте в сравнении дополнительно привести числа к типу int или float, возможно, где то сравниваются строки (да, <, > могут работать как strcmp).
  • Михаил Ливач, float с округлением до 2 символов не вариант?
  • Одиночка Айс, если я Вас правильно понял, то зависит от задачи. Тут на скриншотах было 2 знака после запятой, но это не даёт возможности судить обо всех значениях. Если нужно только 2 знака после запятой, берёте EPSILON = 0.01 .
  • Михаил Ливач, да что за эпсилон такой? зачем он?
  • Одиночка Айс, почитайте тут, например. Нужен потому, что вещественные числа нельзя проверять на равенство в силу неточности представления.
  • Михаил Ливач, спасибо
  • Ошибка была в том, что вещественные числа нельзя сравнивать напрямую. ( подробнее - в комментарии к вопросу)

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Анна SEO Ответ

    Функция usort в PHP используется для сортировки массива с использованием пользовательской функции сравнения. Она позволяет определить свой собственный порядок сортировки элементов массива. Однако, если usort работает не так, как ожидается, это может быть вызвано несколькими причинами.

    Во-первых, возможно, что пользовательская функция сравнения, которая передается в качестве аргумента функции usort, содержит ошибку. Например, она может неправильно определять порядок элементов или возвращать некорректное значение. В таком случае необходимо внимательно просмотреть код функции сравнения и устранить ошибку.

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

    Также стоит учитывать, что функция usort изменяет исходный массив, поэтому перед ее вызовом стоит скопировать исходный массив, если нужно сохранить его состояние. Иногда это может привести к нежелательным изменениям данных.

    Другой возможной причиной неправильной работы usort может быть некорректное использование ключей массива. Если ключи не уникальны или не соответствуют ожидаемому порядку сортировки, это также может привести к непредсказуемым результатам.

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

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно