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

时间:2012-03-06 22:11:22

标签: javascript

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

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

但它根本不起作用。

是否有一种直截了当的方法,优选的方式是不需要手动滚动我自己的排序算法或将数组的每个元素复制到一个新的元素中?

7 个答案:

答案 0 :(得分:179)

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

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

// Or:
return Array.prototype.slice.call(arr).sort(); // For array-like objects

答案 1 :(得分:93)

使用es6(非深拷贝)的另一种方法:

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

spread-syntax as array literal(从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

答案 2 :(得分:52)

尝试以下

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

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

答案 3 :(得分:28)

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

var foo,
    bar;
foo = [3,1,2];
bar = foo.slice().sort();

答案 4 :(得分:5)

你也可以这样做

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

答案 5 :(得分:4)

任何想要进行深度复制的人(例如,如果您的数组包含对象)都可以使用:

let arrCopy = JSON.parse(JSON.stringify(arr))

然后,您可以在不更改arrCopy的情况下对arr进行排序。

arrCopy.sort((obj1, obj2) => obj1.id > obj2.id)

请注意:对于大型阵列,这可能会很慢。

答案 6 :(得分:1)

我的大多数副本使用Object.assign()

var copyArray = Object.assign([], originalArray).sort();

然而,在浏览了OP评论之后,我研究了一些深度复制,结果发现Object.assign不仅执行浅拷贝,而且只选择可枚举和自己的属性(如this post中所述)