Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

usort issue with decimal numbers

I'm currently trying to sort a multidimensional array by its subvalues. The structure of the array is:

[0] => Array
    (
        [id] => 87
        [sold] => 50
        [stock] => 991
        [speed] => 1.5
        [days_left] => 660.66666666667
    )

[1] => Array
    (
        [id] => 97
        [sold] => 20
        [stock] => 120
        [speed] => 1.2
        [days_left] => 100
    )

[2] => Array
    (
        [id] => 36
        [sold] => 2
        [stock] => 1020
        [speed] => 1.02
        [days_left] => 1000
    )

The code I'm using is:

usort($data, function($a, $b) { return $a[$_GET['sortby']] - $b[$_GET['sortby']]; });

where the $_GET['sortby'] variable equals the key.

So far so good, everthing is working, it sorts all values correctly EXCEPT the speed! First, I thought it has something to do with the decimal numbers, but the days_left include also decimals and are sorted correctly.. :/

Correct output (days_left):

[0] => Array
    (
        [id] => 97
        [sold] => 20
        [stock] => 120
        [speed] => 1.2
        [days_left] => 100
    )

[1] => Array
    (
        [id] => 87
        [sold] => 50
        [stock] => 991
        [speed] => 1.5
        [days_left] => 660.66666666667
    )

[2] => Array
    (
        [id] => 36
        [sold] => 2
        [stock] => 1020
        [speed] => 1.02
        [days_left] => 1000
    )

Wrong output (speed):

[0] => Array
    (
        [id] => 97
        [sold] => 20
        [stock] => 120
        [speed] => 1.2
        [days_left] => 100
    )

[1] => Array
    (
        [id] => 87
        [sold] => 50
        [stock] => 991
        [speed] => 1.5
        [days_left] => 660.66666666667
    )

[2] => Array
    (
        [id] => 36
        [sold] => 2
        [stock] => 1020
        [speed] => 1.02
        [days_left] => 1000
    )

Hope anybody can help me!

like image 685
Yami Avatar asked May 13 '13 10:05

Yami


2 Answers

See usort docs. Float result will be converted to integer. For correct work use this code:

usort(
    $data, 
    function($a, $b) {
        $result = 0;
        if ($a[$_GET['sortby']] > $b[$_GET['sortby']]) {
            $result = 1;
        } else if ($a[$_GET['sortby']] < $b[$_GET['sortby']]) {
            $result = -1;
        }
        return $result; 
    }
);
like image 145
Eugene Avatar answered Nov 19 '22 12:11

Eugene


Try strnatcmp():

usort($output, function($a, $b) {
    return strnatcmp($b->days_left, $a->days_left);
});
like image 3
Faridul Khan Avatar answered Nov 19 '22 12:11

Faridul Khan