Search code examples
phparrayssortingmultidimensional-arraycustom-sort

Sort an array based on related data in a 2d array


So I've searched for hours but no thread seems to get me to a working solution.

My problem; I've got 2 arrays. 1 array with the user's roles. And one array with all roles with an specific order.

$roles = [
    [
        'id' => 22465,
        'name' => 'Rank 1',
        'position' => 24,
        'color' => 16711680,
    ],
    [
        'id' => 59454,
        'name' => 'Rank 2',
        'position' => 15,
        'color' => 15844367,
    ],
    [
        'id' => 62280,
        'name' => 'Rank 3',
        'position' => 2,
        'color' => 65494,
    ],
    [
        'id' => 67139,
        'name' => 'Rank 4',
        'position' => 10,
        'color' => 1146986,
    ],
    [
        'id' => 75372,
        'name' => 'Rank 5',
        'position' => 25,
        'color' => 1146986,
    ],
    [
        'id' => 75373,
        'name' => 'Rank 6',
        'position' => 18,
        'color' => 1146986,
    ],
];

And I have the user roles array:

$userdata = [
    'roles' => [22465, 59454, 62280, 67139, 75372, 75373],
    'data' => ['irrelevant']
];

I want the user roles array to be sorted to the roles 'position' in the other array. I think the bottleneck is in the part that the array has to be called with the subarray [roles][position] to get the order to work.

The result in the roles subarray should be:

[0] => 75372
[1] => 22465
[2] => 75373
[3] => 59454
[4] => 67139
[5] => 62280

Solution

  • // First, build a lookup table relating id directly to position
    $ranks = [];
    foreach($roles as $role) {
        $ranks[$role['id']] = $role['position'];
    }
    
    var_dump($ranks);
    
    // Now sort the table using the lookup table we just produced
    //
     usort($userdata['roles'], function($a, $b) use ($ranks){
            return $ranks[$b] <=> $ranks[$a];
     });
    
    var_dump($userdata);
    

    Content of userdata array after sorting

    array (size=2)
      'roles' => 
        array (size=6)
          0 => int 75372
          1 => int 22465
          2 => int 75373
          3 => int 59454
          4 => int 67139
          5 => int 62280
      'data' => 
        array (size=1)
          0 => string 'irrelevant' (length=10)