Intereting Posts
Отображение значения из базы данных в динамически созданное текстовое поле в таблице с помощью jQuery Отображение активной ветви навигации Zend без верхнего уровня Можете ли вы получить прозрачный градиент с помощью PHP ImageMagick? php-mail со вложением PDO: Как проверить, действительно ли соединение активно, для реального? Значение операции для нескольких массивов, имеющих один и тот же ключ Передача ассоциативных массивов PHP в XML и из них Неустранимая ошибка: Class 'App \ Http \ Controllers \ Input' не найден при отправке формы В PHP включены файлы, которые делают данные JSON недействительными Как передать пустые значения для пароля в yii2? Груша на окнах, отображающих разные номера версий Как бороться с таймаутами сеанса в запросах AJAX PHP htmlentities () на входе до вставки БД, а не на выходе Ошибка 500 (Внутренняя ошибка сервера) ajax и laravel Повторный просмотр заголовка jquery mobile на разных страницах

Почему мой сортировка usort () не сортируется?

Я переписываю старый скрипт, который выплескивает самый популярный контент, используя usort.

По какой-то причине вывод моего usort на самом деле не сортируется.

Я использую php 5.5 (пожалуйста, не обращайте внимания на использование амортизированной функции mysql_, которая является частью причины, по которой я переписываю этот скрипт).

//store data in array $sort_array = array(); while($row = mysql_fetch_assoc($result)) { //calculate age $age = (strtotime("now") - strtotime($row["DATE"]))/86400;//86400 converts seconds to days //calculate "effective views" via gaussian distribution shown below //y = e^(-(k * x)^2) where k is below $K = 0.1665109222315395512706329289790402095261177704528881;//solved for a half-life of 5 days $effective_views = round($row["VIEWS"] * exp(-pow( $K * $age, 2))); //store data $article = new stdClass; //$article->id = $row["ID"]; $article->effective_views = $effective_views; //$article->title = $row["TITLE"]; //$article->author = $row["AUTHOR"]; $sort_array[] = $article; } //sort array based on effective views usort( $sort_array, function($a, $b) { return -strcmp($a->effective_views, $b->effective_views); } ); echo "<pre>"; print_r($sort_array); 

Результат должен быть отсортирован по эффективным_views в порядке убывания, однако это не так.

Вот выходной дамп:

http://pastebin.com/rV5YwWN7

Пожалуйста, сообщите мне, что я делаю неправильно здесь.

Solutions Collecting From Web of "Почему мой сортировка usort () не сортируется?"

Проблема заключается в использовании strcmp для сравнения чисел ; он сравнивает строки , в лексикографической манере, или «как найденные в словаре». Это означает, что «96» приходит после «503» или раньше, когда заказывается в обратном порядке.

Рассмотрим следующее, которое возвращает отрицательное число, когда a <b, положительное число при a> b и 0 в противном случае – оно эффективно отменяет порядковые номера при использовании с функцией сравнения стиля usort.

 return $a->effective_views - $b->effective_views; 

Вы не должны использовать strcmp для сравнения целых чисел.

Вы должны использовать:

 return $a->effective_views - $b->effective_views; 

вместо

 return -strcmp($a->effective_views, $b->effective_views); 

Вы также можете посмотреть результат:

 echo strcmp(2,10); 

Как вы видите, это 1 а не -1 потому что первый символ из 10 строк равен 1 и 1 до 2

Вы используете strcmp для того, что кажется целым, попробуйте return $a->effective_views - $b->effective_views или наоборот, в зависимости от вашего заказа.

Эта простая песочница показывает, что strcmp работает в лексикографическом стиле.

Strcmp – сравнение двоичных безопасных строк

Вы не можете использовать strcmp, потому что это не сравнение чисел, если вы хотите сравнивать числа с помощью strcmp, вы можете использовать небольшой трюк, подобный этому:

 function cmp($a, $b) { if ($a == $b) { return 0; } return ($a > $b) ? -1 : 1; } $a = array(3, 7, 733, 9, 73, 222, 5, 99, 1, 5, 0); usort($a, "cmp"); foreach ($a as $key => $value) { echo "$key: $value\n"; } 

И если вы хотите использовать Операторы сравнения :

 function cmp2($a, $b) { if(strlen($a)!==strlen($b)){ return -strcmp(strlen($a),strlen($b)); } return -strcmp($a, $b); } $a = array(3, 7, 733, 9, 73, 222, 5, 99, 1, 5, 0); usort($a, "cmp2"); foreach ($a as $key => $value) { echo "$key: $value\n"; } 

Пример: http://sandbox.onlinephpfunctions.com/