Почему usort возвращает массив, когда значения равны PHP до 7.0 - PullRequest
0 голосов
/ 10 февраля 2020

Я пытаюсь использовать usort в массиве и получить другое поведение относительно версии PHP:

$arr1 = [
    [
        'points' => 10,
        'date' => 3,
    ],
    [
        'points' => 10,
        'date' => 2,
    ],
    [
        'points' => 10,
        'date' => 1,
    ]
];

usort($arr1, function ($a, $b) {
    if($a['points'] == $b['points']){
      return 0;
    }
    return ($a['points'] < $b['points']) ? 1 : -1;
});

Этот массив содержит значение "date" и имеет порядок DES C на этом значении после usort, основанного на значении "points", элементы с одинаковым значением "points" инвертируются на PHP 5.6 и сохраняют свой первоначальный порядок на PHP 7.0 ...

Вы можете проверить это онлайн здесь, с различными версиями PHP (пожалуйста, проверьте по PHP 5.6.29 и 7.0.1): http://sandbox.onlinephpfunctions.com/code/2715220539623b4b699ebb3f90a4b01c98eef53d

Как я мог получить одинаковое поведение сортировки на равных точках при любой версии PHP?

Ответы [ 3 ]

2 голосов
/ 10 февраля 2020
    $array = [
        ['points' => 10, 'date' => 3],
        ['points' => 10, 'date' => 2],
        ['points' => 10, 'date' => 1],
    ];

    usort($array, function ($a, $b) {
        if($a['points'] === $b['points']){
            return $b['date'] <=> $a['date'];
        }
        return $a['points'] <=> $b['points'];
    });

    var_dump($array);
2 голосов
/ 10 февраля 2020

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

Чтобы вы могли решить эту проблему с помощью ...

usort($arr1, function ($a, $b) {
    if($a['points'] == $b['points']){
      return $a['date'] - $b['date'];
    }
    return ($a['points'] < $b['points']) ? 1 : -1;
});

Таким образом, если значение points одинаково, тогда используйте date в качестве дифференциатора (предполагая, что сравнение чисел c будет работать.)

1 голос
/ 10 февраля 2020

Как уже отмечали другие, вам нужно отсортировать по более чем одну клавишу. PHP обеспечивает это с помощью compare_func, а также космический корабль <=> * ("). ") для вашего удобства при написании таких функций.

Если ваш compare_func обнаружит, что points равен, он должен продолжить сравнение date и т. д., возвращая первое значение, которое не является нуль. (для этого можно использовать оператор or.)

И, если все ключей сортировки равны, поведение usort() является «непредсказуемым». В этом случае вы не должны предполагать, что записи будут представлены в каком-либо определенном порядке ... даже от одного вызова к usort() к следующему. Если вы думаете, что «эта версия PHP« всегда »делает это таким образом, а эта версия« всегда »делает это каким-то другим образом», предположите, что вы просто ошибаетесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...