массивы JavaScript.прототип.sort () непреднамеренно мутирующий массив

Я пытаюсь отсортировать массив целых чисел так, чтобы расположить их в порядке, который сформирует наибольшее целое число. Например, [99, 901] следует отсортировать как [99, 901], потому что 99,901 > 90,199. И [91, 991] следует отсортировать как [991, 91], потому что 99,191 > 91,991.

Для этого я использую Array.прототип.sort (), передавая функцию compare в блоке кода ниже в качестве аргумента. Аргументом этой функции сравнения является массив массивов (каждое целое число сначала разбивается на массив одноразрядных целых чисел): [[9,1],[9,9,1]].

Моя проблема заключается в том, что в то время как эта функция сравнения работает, она возвращает массив, который имеет некоторые элементы усеченные. Видимо это связано с тем, что я вызываю Array.прототип.shift (), когда необходимо сравнить второй (или третий, четвертый и т.д.)) элементы двух целых чисел. Я не ожидал этого, но не могу найти обходной путь.

Например, код под выходами

[[9],[1,9]]

в то время как то, что мне нужно

[[9,9],[9,1,9]]

Можете ли вы сказать мне, как я могу пересмотреть свою функцию сравнения, чтобы получить выход, который я ищу?

Спасибо!

var compare = function(a, b){

    if(a.length === 1 || b.length === 1){
        return (b[0] - a[0]);
    }

    else if(a[0] !== b[0]){
        return compare(a[0], b[0]);
    }

    else if(a[0] === b[0]){
        if(a.length !== 1){
            a.shift();
        }
        if(b.length !== 1){
            b.shift();
        }
        return compare(a, b);
    }
};

var example = function(){

    var digits = [[9,9],[9,1,9]];
    digits.sort(compare);
    console.log(digits);
};

example();

2 ответа

  1. самый простой (но неэффективный) способ сделать это-скопировать массивы:

    var compare = function(a, b){
    a = a.slice();
    b = b.slice();
    
  2. Хотя вы уже приняли ответ, я все равно хотел бы ответить на ваш вопрос… «как я могу пересмотреть свою функцию сравнения?», потому что вам действительно нужно: в настоящее время это дает неправильные результаты для некоторых входов, как здесь:

    var compare = function(a, b){
    
        if(a.length === 1 || b.length === 1){
            return (b[0] - a[0]);
        }
    
        else if(a[0] !== b[0]){
            return compare(a[0], b[0]);
        }
    
        else if(a[0] === b[0]){
            if(a.length !== 1){
                a.shift();
            }
            if(b.length !== 1){
                b.shift();
            }
            return compare(a, b);
        }
    };
    
    console.log('this should return a number greater than 0:');
    console.log(compare([8,1],[8,1,9,2]));

    Вот как это исправить, и сделать это без мутации также:

    var compare = function(a, b){
        for (var i = 0; i < a.length || i < b.length; i++) {
            var diff = b[i % b.length] - a[i % a.length];
            if (diff) return diff;
        }
        return 0;
    };
    
    console.log('this should return a number greater than 0:');
    console.log(compare([8,1],[8,1,9,2]));
    var digits = [[8,1],[8,1,9,2]];
    digits.sort(compare);
    console.log('sorted:');
    console.log(JSON.stringify(digits));