2

I have a multidimensional array and I want to sort based off the 'rating'... but I also want the index to start at 1 which is what I used when manually creating these. When I use usort it rearranges the array but now they start at index 0 so I can't do a loop from 1 - 6 because 6 is undefined after sort.

It was cleaner to start my $array at 1 so $player[$i] represented that actual player number. Here's what my array looks like before sort

$player[1]['rating'] = 8
$player[2]['rating'] = 5
$player[3]['rating'] = 10

Here's my sort function:

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

And I call it by

usort($player, 'sortByRating');
2
  • "Player number" meaning there's an association that should be kept? I.e. whoever has key 1 should still have key 1 after sorting, but that key may be sorted elsewhere? In that case you should be using uasort. – Otherwise, if the 1 is just used for outputting "1.", you should not bend over backwards here; arrays are zero-indexed, period, add + 1 for visual output when needed. Commented May 16, 2017 at 2:40
  • Probably should just use a foreach() loop or start your for() loop from 0. Commented May 16, 2017 at 2:59

2 Answers 2

3

The easiest way is to add this code after usort:

array_unshift($player,'temp');
unset($player[0]);

Full code:

function sortByrating($a, $b) {
    return $a['rating'] - $b['rating'];
}

$player[1]['rating'] = 8;
$player[2]['rating'] = 5;
$player[3]['rating'] = 10;

usort($player, 'sortByRating');

array_unshift($player,'temp');
unset($player[0]);

print_r($player);

Output:

Array
(
    [1] => Array
        (
            [rating] => 5
        )

    [2] => Array
        (
            [rating] => 8
        )

    [3] => Array
        (
            [rating] => 10
        )

)

UPDATE with posible solution:

function sortByrating($a, $b) {
    return $a['rating'] - $b['rating'];
}

$player[1]['rating'] = 8;
$player[2]['rating'] = 5;
$player[3]['rating'] = 10;

uasort($player, 'sortByRating');

foreach($player as $player_id=>$player_data) {
    $place++;
    $player[$player_id]['place'] = $place;
    $places[$place] = $player_id;
    echo "Player #{$player_id} takes Place #{$place}\n";
}

echo "\nPlayers array: ";
print_r($player);

echo "\nPlaces array: ";
print_r($places);

Ouput:

Player #2 takes Place #1
Player #1 takes Place #2
Player #3 takes Place #3

Players array: Array
(
    [2] => Array
        (
            [rating] => 5
            [place] => 1
        )

    [1] => Array
        (
            [rating] => 8
            [place] => 2
        )

    [3] => Array
        (
            [rating] => 10
            [place] => 3
        )

)

Places array: Array
(
    [1] => 2
    [2] => 1
    [3] => 3
)
Sign up to request clarification or add additional context in comments.

8 Comments

I tried the array_unshit and then unset and that did solve the problem. nice and easy. thanks
@Chief, please, don't forget to mark the best answers when you recieve answers that solves your problems.
If you're using PHP7+, you can use the Spaceship Operator to streamline the comparison code return statement to return $a['rating'] <=> $b['rating'];
I believe uasort works just the same without needing those 2 lines after you sort, as it keeps the indexes I believe.
@Chief, uasort will return Array(2=>5, 1=>8, 3=>10)... it just reorder positions of array rows and technicaly it will return the same array...
|
1

Just simply add the following after your usort:

$player = array_combine(range(1, count($player)), $player);

uasort() can be used such that the array keeps the original keys:

uasort($player, function ($x, $y) { 
    return $x['rating'] - $y['rating']; 
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.