Сортировка Javascript по сумме цифр не работает даже с функцией сравнения. Зачем?

У меня есть функция, которая сортирует массив целых чисел по сумме их цифр, в случае равной суммы цифр, чем сортировать по значениям чисел. Это функция:

function s(g){
    var r=0;
    while(g)r+=g%10,g/=10;
    return r;
}
function digitalSumSort(a) {
    a.sort(function(x,y){
        return s(x)!=s(y)?s(x)-s(y):x-y;
    });
    return a;
}

Иногда это работает нормально, но не получилось при данных теста:

Вход: [100, 22, 4, 11, 31, 103]

Выход: [100, 11, 31, 4, 22, 103]

Ожидаемый результат: [100, 11, 4, 22, 31, 103]

Я не мог понять, почему это происходит, и как это исправить?

Примечание: важно, чтобы код содержал как можно меньше символов!

Изменить: На этот вопрос уже был дан ответ, но я недавно сделал ту же ошибку и подумал об этом. Есть ли способ сделать var действовать как integer (вместо double) когда дано числовое значение. Я научился трюку с использованием пола, но иногда я просто хочу integer операции вместо double (с некоторыми системами они быстрее, и у меня могут быть другие причины).

2 ответа

Решение

Основная проблема с s функция, потому что он продолжает цикл и собирать значения, когда g является дробью.

Кроме того, вместо вычисления значений при сортировке вы можете использовать преобразование Шварца, то есть decorate-sort-undecorate. Вы создаете массив с вычисленными значениями, которые будете использовать для сортировки, сортировки массива, а затем сопоставления с исходными значениями.

function s(g) {
  var r = 0;
  while (g) r += g % 10, g = Math.floor(g/10); // round g down to skip redundent loops when g is a fraction
  return r;
}

function digitalSumSort(a) {
  return a
    .map(function(n) { // create an array with theorigina and the computed values
      return [s(n), n];
    })
    .sort(function(a, b) {
      return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]; // sort by the computed or original values
    })
    .map(function(n) { // get back an array of the original values
      return n[1];
    });
}

console.log(digitalSumSort([100, 22, 4, 11, 31, 103])); // [100, 11, 4, 22, 31, 103]

Спасибо @JJJ, который прокомментировал: "Подсказка: распечатайте, что возвращает s() (console.log(s(22)) и т. Д.)".

Наконец я заметил, что функция s() возвращает неправильные значения.

Этот код работает:

function s(g){
    var r=0;
    while(g)r+=g%10,g=Math.floor(g/10);
    return r;
}
function digitalSumSort(a) {
    a.sort(function(x,y){
        return s(x)!=s(y)?s(x)-s(y):x-y;
    });
    return a;
}
Другие вопросы по тегам