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

IT技术 javascript arrays sorting
2021-01-20 22:04:17

假设我想要一个排序函数,它返回输入数组的排序副本。我天真地尝试了这个

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

但它根本不起作用。

有没有一种直接的方法来解决这个问题,最好是一种不需要手动滚动我自己的排序算法或将数组的每个元素复制到一个新元素的方法?

6个回答

您需要先复制数组,然后再对其进行排序。使用 es6制作浅拷贝的一种方法

const sorted = [...arr].sort();

作为数组文字的传播语法(从 mdn 复制):

var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

这真的很棒。我认为比 concat 和其他方法更容易理解
2021-03-18 22:04:17
对于那些说它不是有效的 JavaScript 的人……它完全有效。如果您使用 Chrome/Safari/Edge 或 Firefox:打开开发控制台,定义一个名为的数组arr并粘贴表达式以查看结果。
2021-03-20 22:04:17
@Cerin 听起来您使用的 JS 版本非常过时。
2021-03-24 22:04:17
这段代码确实有效,但是当我用 Gulp 编译 JS 时,它返回一个错误, SyntaxError: Unexpected token: punc (.)
2021-04-06 22:04:17

只需复制数组。有很多方法可以做到这一点:

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

// Or:
return Array.prototype.slice.call(arr).sort(); // For array-like objects
为什么Array.prototype.slice.call(arr).sort();而不是arr.slice().sort();
2021-03-26 22:04:17
这会进行深度复制,即嵌套对象和数组也会被复制吗?
2021-04-07 22:04:17
@PeterOlson 不,这是一个浅拷贝。如果您真的想要一个深层副本,请使用 Stack Overflow 上的搜索功能找到现有的优秀答案。
2021-04-09 22:04:17
使用concatover say有什么好处slice(0)吗,或者它们几乎都一样?
2021-04-10 22:04:17
Slice 现在被报告为明显更快
2021-04-10 22:04:17

尝试以下

function sortCopy(arr) { 
  return arr.slice(0).sort();
}

slice(0)表达式从元素 0 开始创建数组的副本。

您可以使用不带参数的 slice 来复制数组:

var foo,
    bar;
foo = [3,1,2];
bar = foo.slice().sort();
这个答案太棒了!我很惊讶 JavaScript 允许这种程度的变异。好像不对。再次感谢。
2021-03-30 22:04:17

你也可以这样做

d = [20, 30, 10]
e = Array.from(d)
e.sort()

这样 d 就不会发生变异。

function sorted(arr) {
  temp = Array.from(arr)
  return temp.sort()
}

//Use it like this
x = [20, 10, 100]
console.log(sorted(x))
这个回答不错
2021-03-24 22:04:17