如何在不改变原始数组的情况下对数组进行排序?

464

假设我想要一个排序函数,该函数返回输入数组的排序副本。 我尝试了以下代码:

function sort(arr) {
  return arr.sort();
}

我用下面的测试代码进行验证,结果证明我的sort方法对数组进行了改变。

var a = [2,3,7,5,3,7,1,3,4];
sort(a);
alert(a);  //alerts "1,2,3,3,3,4,5,7,7"

我也尝试了这种方法。

function sort(arr) {
  return Array.prototype.sort(arr);
}

但它根本不起作用。

有没有简单的方法绕过这个问题,最好不需要手动编写自己的排序算法或将数组的每个元素复制到一个新数组中?


1
创建数组的深拷贝并对其进行排序。 - evanmcdonnal
2
@evanmcdonnal 如果只需要重新排序而不是数组中每个项目的副本,则浅复制可能已经足够了。 - Kekoa
“.sort” 要求“this”值为数组,因此对于最后一个片段要工作,您需要执行“.sort.call(arr)”(尽管这并不能解决您的问题)。 - pimvdb
@Kekoa 是的,这是个很好的观点。如果你只打算改变元素的顺序而不改变元素本身,那么就没有必要消耗更多的内存。 - evanmcdonnal
zzzzBov的方法非常有效!https://dev59.com/w2kw5IYBdhLWcg3w2-XH#9592774 - zimmerbimmer
13个回答

0

我知道我的回答可能有点晚,但如果有人再遇到这个问题,我的解决方案可能会有用。

我可以提出另一种使用本地函数的方法,该函数返回一个已排序数组

这段代码仍然改变原始对象,但是与其它实现不同,它返回一个已排序的数组。

// Remember that it is not recommended to extend build-in prototypes 
// or even worse override native functions.  
// You can create a seperate function if you like

// You can specify any name instead of "sorted" (Python-like)

// Check for existence of the method in prototype
if (typeof Array.prototype.sorted == "undefined") {
  // If it does not exist you provide your own method
  Array.prototype.sorted = function () {
    Array.prototype.sort.apply(this, arguments);
    return this;
  };
}

这种解决问题的方法在我的情况下是理想的。


0
要对一个函数进行排序而不改变原始数组,只需要在进行排序之前使用.map()来创建原始数组的副本即可:

const originalArr = [1, 45, 3, 21, 6];
const sortedArr = originalArr.map(value => JSON.parse(JSON.stringify(value))).sort((a, b) => a - b);

console.log(sortedArr); // the logged output will be 1,3,6,21,45

原始数组未被修改,但您可以使用已排序的版本。 JSON.parse(JSON.stringify()) 确保它是深拷贝,而不是浅拷贝。


0

您还可以扩展现有的数组功能。这样可以将不同的数组函数链接在一起。

Array.prototype.sorted = function (compareFn) {
    const shallowCopy = this.slice();
    shallowCopy.sort(compareFn);

    return shallowCopy;
}

[1, 2, 3, 4, 5, 6]
    .filter(x => x % 2 == 0)
    .sorted((l, r) => r - l)
    .map(x => x * 2)

// -> [12, 8, 4]

在TypeScript中相同:

// extensions.ts
Array.prototype.sorted = function (compareFn?: ((a: any, b: any) => number) | undefined) {
    const shallowCopy = this.slice();
    shallowCopy.sort(compareFn);

    return shallowCopy;
}

declare global {
    interface Array<T> {
        sorted(compareFn?: (a: T, b: T) => number): Array<T>;
    }
}

export {}

// index.ts
import 'extensions.ts';


[1, 2, 3, 4, 5, 6]
    .filter(x => x % 2 == 0)
    .sorted((l, r) => r - l)
    .map(x => x * 2)

// -> [12, 8, 4]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接