Javascript JS中本机Array.sort()行为不一致
我想通过将值为2或更大的所有元素移动到数组的末尾来对整数数组进行排序。但是,如果我比较的两个元素都是2或更大,或者都小于2,那么我希望保持它们的当前顺序。我将以下比较函数用于本机的Javascript JS中本机Array.sort()行为不一致,javascript,sorting,Javascript,Sorting,我想通过将值为2或更大的所有元素移动到数组的末尾来对整数数组进行排序。但是,如果我比较的两个元素都是2或更大,或者都小于2,那么我希望保持它们的当前顺序。我将以下比较函数用于本机的.sort(): 但看起来一旦我超过10个元素,它似乎会随机排列小于2的元素,以及大于等于2的元素: [2, 3, 2, 0, 0, 0, 1, 0, 0, 0, 0] => [0, 0, 0, 0, 0, 1, 0, 0, 3, 2, 2] (expected result) =
.sort()
:
但看起来一旦我超过10个元素,它似乎会随机排列小于2的元素,以及大于等于2的元素:
[2, 3, 2, 0, 0, 0, 1, 0, 0, 0, 0] => [0, 0, 0, 0, 0, 1, 0, 0, 3, 2, 2]
(expected result) => [0, 0, 0, 1, 0, 0, 0, 0, 2, 3, 2]
我假设三元运算符中的
-1
总是将左元素保留在左,从而保持顺序(与0
相反,后者可以理解为将它们随机排序)。我知道有一种更好的方法可以在不使用本机.sort()
的情况下进行排序,但我只是想知道它的行为,以及是否有什么方法可以更改比较函数以使它在本机.sort()中正常工作
一种不进行排序的方法是在其上循环,并将大于一个的项附加到一个数组中,将其他项附加到另一个数组中,然后将它们连接起来
var arr = [2, 3, 2, 0, 0, 0, 1, 0, 0, 0, 0];
var shifted = [].concat.apply([],arr.reduce( function (arr, val, ind){
var ind = val > 1 ? 1 : 0;
arr[ind].push(val);
return arr;
},
[[],[]]));
一种不进行排序的方法是在其上循环,将大于一个的项附加到一个数组中,将其他项附加到另一个数组中,并将它们连接起来
var arr = [2, 3, 2, 0, 0, 0, 1, 0, 0, 0, 0];
var shifted = [].concat.apply([],arr.reduce( function (arr, val, ind){
var ind = val > 1 ? 1 : 0;
arr[ind].push(val);
return arr;
},
[[],[]]));
与epascarello的答案非常相似,只是它使用reduceRight向后循环数组。当遇到成员
=
2时,将其拼接并推送到阵列的末端
这应该是有效的,因为数组被修改到位,没有创建新的数组,而epascarello创建了6个额外的数组(包括concat的结果)
var data=[2,3,2,0,0,0,1,0,0,0,0].reduceRight(函数(acc,n,i,data){
如果(n>=2)数据推送(数据拼接(i,1));
返回数据;
},空);
文件。写入(数据);//[0,0,0,1,0,0,0,0,2,3,2]
与epascarello的答案非常相似,只是它使用reduceRight向后循环数组。当遇到成员=
2时,将其拼接并推送到阵列的末端
这应该是有效的,因为数组被修改到位,没有创建新的数组,而epascarello创建了6个额外的数组(包括concat的结果)
var data=[2,3,2,0,0,0,1,0,0,0,0].reduceRight(函数(acc,n,i,data){
如果(n>=2)数据推送(数据拼接(i,1));
返回数据;
},空);
文件。写入(数据);//[0,0,0,1,0,0,0,0,2,3,2]
我已经对sort
方法中发生的情况做了一些控制台日志记录,我得出结论,当排序在数组上迭代时,它将使用比较函数在已移动位置的任何元素上重复。事实上,您的条件更为具体,并且是在一个大数组中,这使得跟踪正在发生的事情变得非常困难。我已经使用了您的第一个示例,并记录了三元运算符的结果以及正在排序的数组。您将获得以下信息:
[2, 3, 2, 0]
-1
[2, 3, 2, 0]
-1
[2, 3, 2, 0]
1
[2, 3, 2, 2]
1
[2, 3, 3, 2]
1
[0, 2, 3, 2]
当您对
[2,3,2,0,0,0,1,0,0,0]
进行排序时,它会经过29次迭代。当您在数组末尾添加额外的0时,它将经过58次迭代。在这额外的29个过程中,我可以想象它将使用您的条件前后洗牌元素。这也许可以解释为什么您没有得到预期的结果。我已经对排序方法中发生的情况做了一些控制台日志记录,我得出结论,当排序在数组上迭代时,它将使用比较函数在移动位置的任何元素上重复。事实上,您的条件更为具体,并且是在一个大数组中,这使得跟踪正在发生的事情变得非常困难。我已经使用了您的第一个示例,并记录了三元运算符的结果以及正在排序的数组。您将获得以下信息:
[2, 3, 2, 0]
-1
[2, 3, 2, 0]
-1
[2, 3, 2, 0]
1
[2, 3, 2, 2]
1
[2, 3, 3, 2]
1
[0, 2, 3, 2]
当您对[2,3,2,0,0,0,1,0,0,0]
进行排序时,它会经过29次迭代。当您在数组末尾添加额外的0时,它将经过58次迭代。在这额外的29个过程中,我可以想象它将使用您的条件前后洗牌元素。这也许可以解释为什么你没有得到预期的结果。你所谓的“原生”实际上是内置的(a或a)。在ECMAScript 2015之前,a(包括函数和方法)可能是用javascript编写的,但在最新规范中,该术语似乎已被替换为。;-)@谢谢,我从来都不太确定它的正确术语是什么,但很高兴知道!没关系,目前语言规范变化非常快。你所说的“本机”实际上是内置的(a或a)。在ECMAScript 2015之前,a(包括函数和方法)可能是用javascript编写的,但在最新规范中,该术语似乎已被替换为。;-)@谢谢,我从来都不太确定它的正确术语是什么,但很高兴知道!没关系,目前语言规范变化非常快。谢谢,我肯定会用另一种方法来代替.sort,但我真的只是想知道为什么.sort会产生这种不一致的行为。Tanks,我肯定会用另一种方法来代替.sort,但是我真的很想知道为什么.sort会产生这种不一致的行为。像这样的书仍然必须将拼接数组减少为具有数据的元素。拼接(I,1)[0]
,拼接的元素将被向后排序:[2,3,4,0,0,0,0,0,1,0,0,0]=>[0,0,0,0,1,0,0,0,4,3,2]
。但是谢谢,我仍然从使用reduceRight
进行反向遍历中学到了很多。像这样的协议仍然需要将拼接数组减少为带有数据的元素。拼接(I,1)[0]
,拼接的元素将被向后排序:[2,3,4,0,0,0,0,1,0,0]=>[0,0,0,0,0,1,0,0,0,0,0,4,3,