phpsortingmultidimensional-arrayarray-multisortarray-column

How can I sort IDs by multiple attributes


I have a multi-dimensional array of fencer ids with 3 attributes (see code below)

Array
(
    [0] => Array
        (
            [id] => 5255
            [ratio] => 1
            [point_difference] => -25
            [given] => 0
        )

    [1] => Array
        (
            [id] => 12256
            [ratio] => 0.5
            [point_difference] => -6
            [given] => 15
        )

    [2] => Array
        (
            [id] => 3473
            [ratio] => 0.83333333333333
            [point_difference] => -26
            [given] => 4
        )

    [3] => Array
        (
            [id] => 10478
            [ratio] => 0.16666666666667
            [point_difference] => -16
            [given] => 12
        )

    [4] => Array
        (
            [id] => 10256
            [ratio] => 0
            [point_difference] => -15
            [given] => 10
        )
)

I want to sort the fencers by ratio then point_difference then given

I tried multisport with array_columns but it messes up the keys of the column arrays and I need the keys to be the ids of the fencers so I can update the database with the ranking. ($ARRAY_fencers is the name of the multi-dimensional seen above)

//define columns
    $ratio_column = array_column($ARRAY_fencers, "ratio", "id");
    $point_diff_column = array_column($ARRAY_fencers, "point_difference", "id");
    $given_points_column = array_column($ARRAY_fencers, "given", "id");

     //start sorting the array array
    if (!array_multisort($ratio_column, SORT_DESC, SORT_NUMERIC, $point_diff_column, SORT_DESC, SORT_NUMERIC, $given_points_column, SORT_DESC, SORT_NUMERIC, $ARRAY_fencers)) {
        echo "CRITICAL ERROR: array_multisort could not complete the sort!";
    } 

If I try to get the keys of a column after sorting I just get 0, 1, 2, ... not the ids, but if I do it before the sort I get the IDs and perfectly but not in order obviously.

I aim to get the keys of one of the columns and use that array to update the database.

//update competitors temp ranking
    $temp_ranking_array = array_keys($given_points_column);

Is there something I'm doing wrong or should I use something else?

Thanks for your answer!


Solution

  • You don't need to index by id in the three array_column uses before the sort, and as you've seen they will be re-indexed after the sort anyway.

    Associative (string) keys will be maintained, but numeric keys will be re-indexed.

    So after the sort just do:

    $ARRAY_fencers = array_column($ARRAY_fencers, null, "id");
    

    To get the keys you can just use the first item without knowing it's key, or do it the way you're currently doing it:

    $temp_ranking_array = array_keys(reset($ARRAY_fencers));
    

    I don't create new variables unless I need them for another reason:

    array_multisort(array_column($ARRAY_fencers, "ratio"), SORT_DESC, SORT_NUMERIC,
                    array_column($ARRAY_fencers, "point_difference"), SORT_DESC, SORT_NUMERIC,
                    array_column($ARRAY_fencers, "given"), SORT_DESC, SORT_NUMERIC,
                    $ARRAY_fencers);