0

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!

2 Answers2

0

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);
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • Wow, thanks for the quick answer. It was really helpful. I didn't know array_multisort re-indexes these larger numeric values as well. The code now works like a charm! – KMarcell KMP Jan 05 '21 at 21:28
-1
$ratio = [];
$point_difference = [];
$given = [];
foreach($arr as $a){
    $ratio[] = array('id'=>$a['id'],'value'=>$a['ratio']);
    $point_difference[] = array('id'=>$a['id'],'value'=>$a['point_difference']);
    $given[] = array('id'=>$a['id'],'value'=>$a['given']);
}
usort($ratio,"sort_multi");
usort($point_difference,"sort_multi");
usort($given,"sort_multi");
function sort_multi($a, $b){
    if($a['value'] == $b['value']) return 0;
    return ($a['value']<$b['value'])?-1:1;
}
  • Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Doj Jan 06 '21 at 02:31