Обратный вызов ArraySort не сортирует мой массив в правильном порядке - PullRequest
0 голосов
/ 10 января 2019

Использование ColdFusion для сортировки многомерного массива на основе поля «Цена за кв. Фут» от высокого к низкому.

Он был в производстве и работал в тестировании, но возник случай, который дал странные, несортированные результаты. Я также запустил это на сайте CFDOCS, используя их ArraySort код и получил те же, неправильные результаты сортировки.

Как видите, результаты даже не отсортированы.

Вот мой код:

figures = [
   {name='carl',price='117.5'},
   {name='fen',price='116.4'},
   {name='joe',price='86.3'}
];

arraySort(figures, function (a, b){
   return compare(b.price, a.price);
});
writeDump(figures);

Результаты:

NAME    joe
PRICE   86.3

NAME    carl
PRICE   117.5

NAME    fen
PRICE   116.4

Должен быть отсортирован в следующем порядке: 117,5, 116,4, 86,3.

Я полагаю, что это сортировка таким образом, что 86.3 выглядит больше, чем остальные, потому что начинается с 8? Я также пробовал без кавычек и получил неправильные результаты.

Я запустил этот же код на cfdocs.org и получил те же неверные результаты.

Я что-то делаю неправильно в параметрах сортировки или в обратном вызове?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Функция обратного вызова ArraySort"сравнивает два элемента массива" одновременно и должна возвращать одно из следующих значений:

  • -1, если первый элемент меньше , второй
  • 0, если первый элемент равен , второй
  • 1, если первый элемент больше , второй

Хотя функция compare () возвращает 1, 0 или -1, она сравнивает элементы как строки , что не приведет к ожидаемый порядок для числовых значений. Как предложил Шон, добавление некоторого кода отладки покажет результаты каждого сравнения:

arraySort(figures, function (a, b){

       local.num = compare(a.price, b.price);
       local.text = local.num == -1 ? " less than " : (local.num == 0 ? " equals " : " greater than");
       writeOutput("<br> "& a.price &" "& local.text &" "& b.price &" => "& local.num );

       return local.num ;
});

.. демонстрирует, что сравнение string не дает те же результаты, что и числовое сравнение:

  • 116,4 меньше 117,5 => -1
  • 86,3 больше 116,4 => 1
  • 86,3 больше, чем 117,5 => 1
  • 1117,3 меньше 117,5 => -1
  • 1117,3 меньше 116,4 => -1

Чтобы отсортировать значения "цены" в виде чисел, используйте арифметические операторы вместо сравнения (). Для по убыванию порядка (от высокого к низкому):

arraySort(figures, function (a, b){
   return (b.price < a.price) ? -1 : (b.price == a.price ? 0 : 1);
});

Для в порядке возрастания (от низкого к высокому), просто поменяйте местами сравнения:

arraySort(figures, function (a, b){
   return (a.price < b.price) ? -1 : (a.price == b.price ? 0 : 1);
});

Пример выполнения

0 голосов
/ 11 января 2019

Рассмотрим функцию compare(). Может возвращать -1, 0 или 1. Только 0 считается ложным. Чтобы исправить это вам нужно

 arraySort(figures, function (a, b){
  return compare(b.price, a.price) == 1 ? 1 : 0;     
 });
 writeDump(figures);
...