Search code examples
phparraysarray-multisort

Sorting an array by multiple fields


In my backend I have some code handling teams for a round robin group tournament, and in the end teams are returned in an array and contains match results/stats etc.

I have the following array which I want to sort by two fields in the following order: points (desc), round_difference (desc).

The final and correct order would be: TeamOne, TeamThree, TeamTwo.

How would I go on about this with an array in this format? Is it possible at all? I have looked into array_multisort() however my array keys/structure overall is a bit "odd" compared to the other code examples I found here on the page and was very confusing to me.

Hopefully someone can assist me in this.

Array
(
    [1] => Array
        (
            [1] => Array
                (
                    [id] => 1
                    [group] => 1
                    [name] => TeamOne
                    [tag] => One
                    [matches] => Array
                        (
                            [played] => 1
                            [won] => 0
                            [ot_won] => 1
                            [ot_lost] => 0
                            [lost] => 0
                            [round_difference] => 3
                            [points] => 2
                        )

                )

            [238] => Array
                (
                    [id] => 238
                    [group] => 1
                    [name] => TeamTwo
                    [tag] => Two
                    [matches] => Array
                        (
                            [played] => 0
                            [won] => 0
                            [ot_won] => 0
                            [ot_lost] => 0
                            [lost] => 0
                            [round_difference] => 0
                            [points] => 0
                        )

                )

            [14] => Array
                (
                    [id] => 14
                    [group] => 1
                    [name] => TeamThree
                    [tag] => Three
                    [matches] => Array
                        (
                            [played] => 1
                            [won] => 0
                            [ot_won] => 0
                            [ot_lost] => 1
                            [lost] => 0
                            [round_difference] => -3
                            [points] => 1
                        )
                )
        )

Solution

  • Try uasort() instead and compare the keys like so:

    uasort($arr[1],function($a,$b){
        # If the points are more/less right off the bat, return results
        if($a['matches']['points'] < $b['matches']['points'])
            return true;
        # If they are the same
        elseif($a['matches']['points'] == $b['matches']['points'])
            # Compare round_difference sort by that
            return ($a['matches']['round_difference'] < $b['matches']['round_difference']);
    });
    

    So, sorting something like this:

    $arr    =   array(
        1 => array(
            1 => array(
                    'id' => 1,
                    'group' => 1,
                    'name' => 'TeamOne',
                    'tag' => 'One',
                    'matches' => array(
                            'played' => 1,
                            'won' => 0,
                            'ot_won' => 1,
                            'ot_lost' => 0,
                            'lost' => 0,
                            'round_difference' => 3,
                            'points' => 2
                        )
    
                ),
            238 => array
                (
                    'id' => 238,
                    'group' => 1,
                    'name' => 'TeamTwo',
                    'tag' => 'Two',
                    'matches' => array(
                            'played' => 0,
                            'won' => 0,
                            'ot_won' => 0,
                            'ot_lost' => 0,
                            'lost' => 0,
                            'round_difference' => 0,
                            'points' => 0,
                        )
    
                ),
            14 => array
                (
                    'id' => 14,
                    'group' => 1,
                    'name' => 'TeamThree',
                    'tag' => 'Three',
                    'matches' => array
                        (
                            'played' => 1,
                            'won' => 0,
                            'ot_won' => 0,
                            'ot_lost' => 1,
                            'lost' => 0,
                            'round_difference' => '-3',
                            'points' => 1,
                        )
    
                ),
            17 => array
                (
                    'id' => 17,
                    'group' => 1,
                    'name' => 'TeamFive',
                    'tag' => 'Five',
                    'matches' => array
                        (
                            'played' => 1,
                            'won' => 0,
                            'ot_won' => 0,
                            'ot_lost' => 1,
                            'lost' => 0,
                            'round_difference' => '-3',
                            'points' => 2,
                        )
    
                )
            )
        );
    

    Gives you:

    Array
    (
        [1] => Array
            (
                [1] => Array
                    (
                        [id] => 1
                        [group] => 1
                        [name] => TeamOne
                        [tag] => One
                        [matches] => Array
                            (
                                [played] => 1
                                [won] => 0
                                [ot_won] => 1
                                [ot_lost] => 0
                                [lost] => 0
                                [round_difference] => 3
                                [points] => 2
                            )
    
                    )
    
                [17] => Array
                    (
                        [id] => 17
                        [group] => 1
                        [name] => TeamFive
                        [tag] => Five
                        [matches] => Array
                            (
                                [played] => 1
                                [won] => 0
                                [ot_won] => 0
                                [ot_lost] => 1
                                [lost] => 0
                                [round_difference] => -3
                                [points] => 2
                            )
    
                    )
    
                [14] => Array
                    (
                        [id] => 14
                        [group] => 1
                        [name] => TeamThree
                        [tag] => Three
                        [matches] => Array
                            (
                                [played] => 1
                                [won] => 0
                                [ot_won] => 0
                                [ot_lost] => 1
                                [lost] => 0
                                [round_difference] => -3
                                [points] => 1
                            )
    
                    )
    
                [238] => Array
                    (
                        [id] => 238
                        [group] => 1
                        [name] => TeamTwo
                        [tag] => Two
                        [matches] => Array
                            (
                                [played] => 0
                                [won] => 0
                                [ot_won] => 0
                                [ot_lost] => 0
                                [lost] => 0
                                [round_difference] => 0
                                [points] => 0
                            )
    
                    )
    
            )
    
    )