phparrayssortingmultidimensional-array

Sort rows of a 2d array by a column of float values in a descending direction


I have an array $scores as per below.

What I am trying to do is sort the array based on the numeric value in a descending order. I've tried defining functions like suggested here and other ways but haven't been able to do it.

array (
    0 => array ( 0 => 'B.Howell', 1 => 16.8, ),
    1 => array ( 0 => 'B.Osweiler', 1 => 14.88, ),
    2 => array ( 0 => 'K.Ballage', 1 => 13.7, ),
    3 => array ( 0 => 'F.Owusu', 1 => 8.8, ),
    4 => array ( 0 => 'I.Ford', 1 => 6.3, ),
    5 => array ( 0 => 'B.Radcliff', 1 => 6.4, ),
    6 => array ( 0 => 'D.Fales', 1 => 3.96, ),
    7 => array ( 0 => 'L.Carroo', 1 => 4.9, ),
    8 => array ( 0 => 'R.Scott', 1 => 2.5, ),
    9 => array ( 0 => 'M.Lewis', 1 => 2.4, ),
    10 => array ( 0 => 'T.Duarte', 1 => 3.2, ),
    11 => array ( 0 => 'J.Langford', 1 => 2.8, ),
    12 => array ( 0 => 'A.Derby', 1 => 1.1, ),
    13 => array ( 0 => 'D.Morgan', 1 => 1.2, ),
)

The solutions offered using usort I've tried previously and could not get them to work and still can't. It does tend to sort the array in somewhat of a descending order, however, there still exists outliers, see the following before and after images.

function mySort($a, $b) {
    return $b[1] - $a[1];
}

usort($scores, 'mySort');

BEFORE IMAGE

AFTER IMAGE


Solution

  • It is working as expected with usort() for DESCENDING order of numeric values

    $b['1'] - $a['1'] its sorts numeric value descending order

    $a['1'] - $b['1'] its sorts numeric value ascending order

    <?php
    $array = array ( array ('B.Osweiler',14.88 ), 
                     array ('D.Fales', 3.96), 
                     array ('B.Radcliff', 6.4 ), 
                     array ('K.Ballage', 13.7 ), 
                     array ('J.Langford', 2.8 ),
                     array ('B.Howell', 16.8 ) );
    
    print "Before Sort". PHP_EOL;;
    print_r($array);
    usort($array, function($a, $b) {
        return $b['1'] - $a['1']; //see this line carefully
    });
    
    print "After Sort". PHP_EOL;
    print_r($array);
    ?>
    

    DEMO: https://3v4l.org/bWdIq

    EDIT: I've added the edit as per the new modification on the question that will fix your existing outliers.

    <?php
    $array = array ( 0 => array ( 0 => 'B.Howell', 1 => 16.8, ), 1 => array ( 0 => 'B.Osweiler', 1 => 14.88, ), 2 => array ( 0 => 'K.Ballage', 1 => 13.7, ), 3 => array ( 0 => 'F.Owusu', 1 => 8.8, ), 4 => array ( 0 => 'I.Ford', 1 => 6.3, ), 5 => array ( 0 => 'B.Radcliff', 1 => 6.4, ), 6 => array ( 0 => 'D.Fales', 1 => 3.96, ), 7 => array ( 0 => 'L.Carroo', 1 => 4.9, ), 8 => array ( 0 => 'R.Scott', 1 => 2.5, ), 9 => array ( 0 => 'M.Lewis', 1 => 2.4, ), 10 => array ( 0 => 'T.Duarte', 1 => 3.2, ), 11 => array ( 0 => 'J.Langford', 1 => 2.8, ), 12 => array ( 0 => 'A.Derby', 1 => 1.1, ), 13 => array ( 0 => 'D.Morgan', 1 => 1.2, ), );
    
    
    print '<pre>';
    print "Before Sort". PHP_EOL;;
    print_r($array);
    usort($array, function($a, $b) {
        if($a[1]==$b[1]){
            return 0;
        }
    
        return ($a[1] > $b[1]) ? -1 : 1;
    });
    
    print "After Sort". PHP_EOL;
    print_r($array);
    ?>
    

    DEMO: https://3v4l.org/c4UmQ