Search code examples
phparrayssortingnatural-sort

Sort an array of associative arrays by multiple columns using a combination of ascending, descending, regular, numeric, and natural sorting


Is it possible to sort a multidimensional array by multiple columns using natural sort in PHP? Here is an example. Suppose I have a 2D array of data, e.g.,

$array[1]['Name'] = 'John';
$array[1]['Age'] = '20';
$array[1]['Code'] = 'ABC 12';

$array[2]['Name'] = 'John';
$array[2]['Age'] = '21';
$array[2]['Code'] = 'ABC 1';

$array[3]['Name'] = 'Mary';
$array[3]['Age'] = '20';
$array[3]['Code'] = 'ABC 10';

I want to sort this array by name (ASC), then by age (DESC), and by code (ASC), all will be sorted naturally. Basically that will be array_multisort with natural sort.

I found many solutions about this topic on the web. Unfortunately, they only support sorting by one column, not multiple column.


Solution

  • I think you have to implement a custom comparison function for this behavior:

    function myCmp($a, $b) {
     $nameCmp = strnatcasecmp($a['Name'], $b['Name']);
     $ageCmp = strnatcasecmp($a['Age'], $b['Age']);
     $codeCmp = strnatcasecmp($a['Code'], $b['Code']);
    
     if ($nameCmp != 0) // Names are not equal
       return($nameCmp);
    
     // Names are equal, let's compare age
    
     if ($ageCmp != 0) // Age is not equal
       return($ageCmp * -1); // Invert it since you want DESC
    
     // Ages are equal, we don't need to compare code, just return the comparison result
       return($codeCmp);
    }
    

    Then you can call usort($array, 'myCmp'); and should get the desired sorting