проблема сорта с десятичными числами

В настоящее время я пытаюсь сортировать многомерный массив по его значениям. Структура массива:

[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 ) 

Код, который я использую:

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

где переменная $ _GET ['sortby'] равна ключу.

Пока все хорошо, все работает, он правильно сортирует все значения. ИСКЛЮЧАЕТ скорость! Во-первых, я думал, что это имеет какое-то отношение к десятичным числам, но days_left включает также десятичные знаки и сортируется правильно ..: /

Корректный выход (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 ) 

Неверный выход (скорость):

 [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 ) 

Надеюсь, кто-нибудь может мне помочь!

См. Usort docs. Результат поплавка будет преобразован в целое. Для правильной работы используйте этот код:

 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; } ); 

В PHP-документе есть комментарий, который имеет решение этой проблемы. Большое спасибо этому парню.

Вот функция для сортировки многомерных массивов с десятичными числами:

 function usortWithFloatVals() { $arguments = func_get_args(); $array = $arguments[0]; $code = ''; for ($c = 1; $c < count($arguments); $c += 2) { if (in_array($arguments[$c + 1], array("ASC", "DESC"))) { $code .= 'if ($a["'.$arguments[$c].'"] != $b["'.$arguments[$c].'"]) {'; if ($arguments[$c + 1] == "ASC") { $code .= 'return ($a["'.$arguments[$c].'"] < $b["'.$arguments[$c].'"] ? -1 : 1); }'; } else { $code .= 'return ($a["'.$arguments[$c].'"] < $b["'.$arguments[$c].'"] ? 1 : -1); }'; } } } $code .= 'return 0;'; $compare = create_function('$a,$b', $code); usort($array, $compare); return $array; } 

Используйте его так же, как вы используете usort() :

 usortWithFloatVals($data, function($a, $b) { return ($a[$_GET['sortby']] - $b[$_GET['sortby']]) ? 1 : -1; });