Javascript array. prototype.sort()无意中改变了数组

Javascript Array.prototype.sort() unintentionally mutating array

本文关键字:无意中 改变 数组 array prototype sort Javascript      更新时间:2023-09-26

我正试图对整数数组进行排序,以便将它们按形成最大整数的顺序排列。例如,[99,901]应该排序为[99,901],因为99,901> 90,199。而[91,991]应该排序为[991,91],因为99,191> 91,991。

要做到这一点,我使用Array.prototype.sort(),在下面的代码块中传递比较函数作为参数。这个比较函数的参数是一个数组的数组(每个整数首先被分割成一个单位数整数数组):[[9,1],[9,9,1]]。

我的问题是,虽然这个比较函数工作,它返回一个数组,其中有一些元素被截断。显然,这是由于我在需要比较两个整数的第二个(或第三个,第四个等)元素时调用Array.prototype.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();

最简单(但效率较低)的方法是复制数组:

var compare = function(a, b){
a = a.slice();
b = b.slice();

虽然你已经接受了答案,但我还是想回答你的问题…"如何修改我的比较函数?",因为您确实需要:它目前会为某些输入提供错误的结果,例如:

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