Массив php order несколько раз, но сохраняйте предыдущие порядки - PullRequest
0 голосов
/ 30 сентября 2018

Итак, мне нужно составить список результатов команды, но мне нужно их отсортировать.Я не могу сделать это SQL (так как данные должны быть рассчитаны каждый раз).В настоящее время я пытался отсортировать данные следующим образом:

usort($result, function($a, $b)
{
    return $a['out_of_time'] - $b['out_of_time'] && $a['tot_controls'] < $b['tot_controls'] && $a['tot_gtks'] < $b['tot_gtks'] && $a['distance'] < $b['distance'];
});

, но это совсем не сработало ... у меня есть следующие данные:

[
    {
        "team_number": 101,
        "pilot": "Robin Tralala",
        "navigator": "Another Person",
        "distance": 0,
        "points_per_gtk": {
            "gtk_1": 2,
            "gtk_2": 2
        },
        "tot_gtks": 4,
        "tot_timecontrols": 2,
        "tot_controls": 20,
        "tot_points": 22,
        "out_of_time": false
    },
    {
        "team_number": 102,
        "pilot": "Bertje Bibber",
        "navigator": "Derp Kwakkel",
        "distance": 0,
        "points_per_gtk": {
            "gtk_1": 4,
            "gtk_2": 1
        },
        "tot_gtks": 5,
        "tot_timecontrols": 1,
        "tot_controls": 0,
        "tot_points": 1,
        "out_of_time": false
    }
]

Ну, мне нужно отсортировать по tot_controls, затем по points_per_gtk значениям, а затем по distance.Как я мог сделать это в PHP?

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

Я написал еще немного кода, и дошел до этого;

usort($result, function($a, $b)
{
    $strafpunten = (int)$a['tot_timecontrols'] <=> (int)$b['tot_timecontrols'];

    foreach($a['points_per_gtk'] as $gtk_name => $points)
    {
        $gtk_points = (int)$a['points_per_gtk'][$gtk_name] <=> (int)$b['points_per_gtk'][$gtk_name];

        if($gtk_points)
        {
            return $gtk_points;
        }
    }

    if($strafpunten)
    {
        return $strafpunten;
    }

    return (int)$a['distance'] <=> (int)$b['distance'];
});

Iпросто действительно не знаю, правильно ли это сортируется ...

1 Ответ

0 голосов
/ 30 сентября 2018

Не так давно я написал библиотеку php для этой конкретной цели .

Вы можете использовать ее так:

<?php
use Stratadox\Sorting\ArraySorter;
use Stratadox\Sorting\Sort;

$table = [
    ['name' => 'Bar', 'rating' => 1],
    ['name' => 'Foo', 'rating' => 3],
    ['name' => 'Baz', 'rating' => 1],
];
$sorter = new ArraySorter();
$table = $sorter->sortThe($table, 
    Sort::descendingBy('rating', Sort::descendingBy('name'))
);

assert($table == [
    ['name' => 'Foo', 'rating' => 3],
    ['name' => 'Baz', 'rating' => 1],
    ['name' => 'Bar', 'rating' => 1],
]);

В вашем случае,это будет:

$sorted = (new ArraySorter())->sortThe($result, 
    Sort::descendingBy('out_of_time', 
        Sort::descendingBy('tot_controls', 
            Sort::descendingBy('tot_gtks', 
                Sort::descendingBy('distance')
            )
        )
    )
);

Измените descending на ascending, где это необходимо.

Вы можете просто установить библиотеку, используя composer require stratadox/sorting.

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

$sorted = (new NestedArraySorter())->sortThe($result, 
    Sort::descendingBy('part_one.total', 
        Sort::descendingBy('part_one.gtk', 
            Sort::descendingBy('part_one.distance')
        )
    )
);

Остерегайтесь того, что при использовании NestedArraySorter возможность достижения смещений массива, содержащих точки, теряется.

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