JS

时间:2016-04-14 04:36:28

标签: javascript sorting

我想通过将值为2或更大的所有元素移动到数组的末尾来对整数数组进行排序。但是,如果我比较两个或两个以上的元素,或者两者都小于2,那么我想保持它们的当前顺序。我使用以下比较函数与原生.sort()

function customSort(a, b) {
  return (a >= 2 && b < 2) ? 1 : -1;
}

它似乎适用于以下情况:

[2, 3, 2, 0] => [0, 2, 3, 2]
[2, 3, 2, 0, 0, 0, 1, 0, 0, 0] => [0, 0, 0, 1, 0, 0, 0, 2, 3, 2]

但看起来,一旦我超过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()

正常工作

3 个答案:

答案 0 :(得分:2)

在没有排序的情况下执行此操作的方法是循环遍历它并将一对一的数据和其他项目添加到另一个数组并加入它们。

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;
                                              },
                                              [[],[]]));

答案 1 :(得分:1)

与epascarello的答案非常相似,只是它使用 reduceRight 向后循环数组。遇到成员>= 2时,它会被拼接并推到数组的末尾。

这应该是有效的,因为数组被修改到位,没有创建新数组,而epascarello创建了6个额外的数组(包括 concat 的结果)。

var data = [2, 3, 2, 0, 0, 0, 1, 0, 0, 0, 0].reduceRight(function(acc, n, i, data) {
  if (n >= 2) data.push(data.splice(i, 1));
  return data;
}, null);

document.write(data); // [0, 0, 0, 1, 0, 0, 0, 0, 2, 3, 2]

答案 2 :(得分:1)

我已经对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期间,我想象它会使用你的条件来向前和向后洗牌。这可以解释为什么你没有得到你期望的结果。