Search code examples
phpsortingmultidimensional-arraymixed

Is there a native multi-dimensional, multi-type sort in PHP?


I'm struggling with sorting a multi-dimensional, multi-type array in PHP.

Usually I just use sort and rsort and ksort etc.

This situation doesn't seem to require anything much more complex, but array_multisort doesn't appear to be working (at least not how I'm using it).

My multi-dimensional, multi-type array looks like this:

[
    'Welsh_Harmony' => [
        'Bread_Dip',
        'Cloud_Patterns',
        'Legendary_Sword',
        'Legumes_In_The_Garden',
        'Notice::Balloons',
        'Notice::Corvid',
        'Titanic',
        'novemberMonth',
        'Elephant_Graveyard'
    ],

    'Oak' => [
        'Keyboard'
    ]
]

and array_multisort gives me this (which is only half right):

[
    'Oak' => [
        'Keyboard'
    ],

    'Welsh_Harmony' => [
        'Bread_Dip',
        'Cloud_Patterns',
        'Legendary_Sword',
        'Legumes_In_The_Garden',
        'Notice::Balloons',
        'Notice::Corvid',
        'Titanic',
        'novemberMonth',
        'Elephant_Graveyard'
    ]
]

Whereas the result I'm trying to produce (note the position of 'Elephant_Graveyard') is:

[
    'Oak' => [
        'Keyboard'
    ],

    'Welsh_Harmony' => [
        'Bread_Dip',
        'Cloud_Patterns',
        'Elephant_Graveyard',
        'Legendary_Sword',
        'Legumes_In_The_Garden',
        'Notice::Balloons',
        'Notice::Corvid',
        'Titanic',
        'novemberMonth'
    ]
]

I have tried using the flag SORT_STRING and SORT_ASC to prompt array_multisort to alphabetically re-order and re-index the second level arrays, but that doesn't seem to work either.

I'm optimistic that there must be a way to execute this kind of multi-dimensional, multi-type sort without writing a custom, recursive function.


Solution

  • array_multisort() can be used to sort several arrays at once, or a multi-dimensional array by one or more dimensions.

    This is basically how you sort different dimensions of your array:

    $ar = array(
       array("10", 11, 100, 100, "a"),
       array(   1,  2, "2",   3,   1)
      );
    array_multisort($ar[0], SORT_ASC, SORT_STRING,
                $ar[1], SORT_NUMERIC, SORT_DESC);
    

    Multi sort accepts variadic params. Read more here, please read scroll down and read the comments.


    Or you can loop through your array's arrays and sort them one by one.

    foreach ($matrix as &$row) { sort($row); } 
    

    However, I think multi-sort would perform much better.