如何正确排序整数数组

pei*_*rix 772 javascript arrays sorting numbers

试图从我知道的数组中获得最高和最低值只包含整数似乎比我想象的要难.

var numArray = [140000, 104, 99];
numArray = numArray.sort();
alert(numArray)
Run Code Online (Sandbox Code Playgroud)

我希望这能表明99, 104, 140000.相反它显示104, 140000, 99.所以似乎排序是将值作为字符串处理.

有没有办法让sort函数实际对整数值进行排序?

aks*_*aks 1113

默认情况下,sort方法按字母顺序对元素进行排序.要以数字方式排序,只需添加一个处理数字排序的新方法(sortNumber,如下所示) -

function sortNumber(a, b) {
  return a - b;
}

var numArray = [140000, 104, 99];
numArray.sort(sortNumber);

console.log(numArray);
Run Code Online (Sandbox Code Playgroud)

编辑:使用ES6箭头功能:

numArray.sort((a, b) => a - b); // For ascending sort
numArray.sort((a, b) => b - a); // For descending sort
Run Code Online (Sandbox Code Playgroud)

  • 尼斯.但是真的没有开箱即用的方法来从javascript中获得数字排序吗? (133认同)
  • 可以使用[箭头功能](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)缩短此代码.`numberArray.sort((a,b)=>(a - b));`耶!我认为这接近开箱即用的方式.**注意:检查您的JS引擎是否支持箭头功能.** (46认同)
  • 啊,这是开箱即用的!但是如果你真的不切实际,你可以在javascript开始时将函数绑定到数组类:// Array.prototype.sortNormal = function(){return this.sort(function(a,b){return a - b})} //现在在任何数组上调用.sortNormal()都会按数字排序 (39认同)
  • @Velthune比较函数应返回-1,0或+1.a> b只会返回true或false. (33认同)
  • 为什么ab而不是a> b.我建议最后一个,以避免操作机器错误 (12认同)
  • Javascript没有打算实现数字排序?这背后的原因是什么? (6认同)
  • @ K._ - 你实际上并不需要括号:`.sort((a,b)=> a - b)` - 所以它甚至更短. (3认同)
  • @Black你应该阅读Array.prototype.sort()文档页面:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort你传入一个比较函数来`sort()`应该返回一个大于零,小于零或零的值. (3认同)
  • 我要求当a = b时不应该改变数组元素的位置.但是上面的代码改变了数组元素的位置,即使它们的值相同.有没有解决方法?谢谢 (2认同)
  • @Black 这正是 `sort()` 的比较函数所期望的。您是否阅读了链接的文档?当 sort() 运行时,它考虑了三种情况,布尔表达式是不够的。在确定两个对象 `a` 和 `b` 的顺序时,`sort()` 确定:(1) `a` 在 `b` 之前,(2) `b` 在 `a` 之前,或 (3 ) `a` 和 `b` 应该按照它们彼此之间的顺序保留,但相对于数组中的其他元素进行排序。让比较器函数返回一个“> 0”、“0”或“< 0”的数字,可以很好地映射到所描述的场景。 (2认同)
  • @vikramvi 如果“b”应该在“a”之后,则“sort()”期望一个负数,如果“a”应该在“b”之后,则期望一个正数。当“b”大于“a”时,“ab”为负数,应在“a”之后;当“a”大于“b”时,“ab”为正,应在“a”之后。使用“ba”可以反转它 - 现在当“a”大于“b”时它是负数并且应该在“a”之后。示例:“[1,9]”:“1-9 = -8”,因此“9”应该按升序排列在“1”之后 - 相反,“9-1”是“8”,所以“1”应该按降序排列在“9”之后。 (2认同)

Mar*_*cks 167

只要建立在上述所有答案的基础上,它们也可以在一行中完成,如下所示:

var numArray = [140000, 104, 99];

// ES5
numArray = numArray.sort(function (a, b) {  return a - b;  });

// ES2015
numArray = numArray.sort((a, b) => a - b);

//outputs: 99, 104, 140000
Run Code Online (Sandbox Code Playgroud)

  • @bambery我认为你不需要专门用于上下文改变的箭头函数...... (12认同)
  • @bodyflex修正:`var arr = [140000,104,99] .sort(function(a,b){return ab;});`.或者更紧凑,在ES6中`let arr = [140000,104,99] .sort((a,b)=> ab);` (8认同)
  • @bambery,你实际上误解了箭头功能正在做什么.你认为它以某种方式将`this`传递给函数,但事实并非如此.它实际上忽略了创建一个`this`和`arguments`变量,它通常会覆盖父变量.你可以在箭头函数中使用`this`的唯一原因是词法范围. (5认同)

Pau*_*xon 70

array.sort默认使用字典排序,对于数字排序,提供自己的函数.这是一个简单的例子:

function compareNumbers(a, b)
{
    return a - b;
}

numArray.sort(compareNumbers);
Run Code Online (Sandbox Code Playgroud)

另请注意,排序工作"就地",不需要分配.

  • 如果 a < b,compareNumbers 返回负数。如果a > b,则为正。如果相等则返回0。 (4认同)
  • 我不明白上面的代码,“return a - b”如何进行升序排序? (3认同)
  • @AliMertCakar,因为它只返回 true 或 false,并且比较函数需要返回负数、零或正数。 (2认同)

nor*_*off 45

只是做.sort((a, b) => a - b)而不是.sort()它自己。除此之外,该数组已就地排序。所以返回值并不重要。

var numArray = [140000, 104, 99];
numArray.sort((a, b) => a - b);
console.log(numArray)
Run Code Online (Sandbox Code Playgroud)


jjj*_*jjs 38

这个答案等同于一些现有的答案,但ECMAScript 6 箭头函数提供了更紧凑的语法,允许我们在不牺牲可读性的情况下定义内联排序函数:

numArray = numArray.sort((a, b) => a - b);
Run Code Online (Sandbox Code Playgroud)

今天大多数浏览器都支持它.

  • @Tristan,使用这种语法仍然可以非常干净地对对象的属性进行排序.如果要排序的对象的属性是一个数字,你可以这样做:`objArray = objArray.sort((a,b)=> a.numProperty - b.numProperty);`如果属性是一个字符串你可以这样做:`objArray = objArray.sort((a,b)=> a.strProperty.localeCompare(b.strProperty));`有人说过,这个问题专门询问有关排序整数数组的问题 (2认同)

dy_*_*dy_ 25

我很惊讶为什么每个人都建议将比较器功能传递给sort(),这使得排序真的很慢!

要对数字进行排序,只需创建任何 TypedArray:

var numArray = new Uint32Array([140000, 104, 99]);
numArray = numArray.sort();
alert(numArray)
Run Code Online (Sandbox Code Playgroud)

  • @Nikolay D 那些没有签名。您可以使用 Int32Array。 (4认同)
  • @Gio 不确定这是真的。内存需求仅为 O(2n),对于包含数百万个项目的数组而言,内存需求仅为几兆字节。至于速度 - 将数组转换为类型化数组,排序和转换回来仍然比使用函数对数组进行排序要快。 (4认同)
  • 使用TypedArray可使排序速度提高约5倍。如果您想更快一些,hpc-algorithms npm包将实现“基数排序”和“计数排序”,这里有一些答案。 (3认同)
  • 有趣的是,一群人在这里讨论性能,而没有(a)提供可运行的基准测试,(b)说明他们正在使用的浏览器/引擎/操作系统/处理器,以及(c)提供任何测量的计时(多次运行的平均值,也使得 null -假设检验) (3认同)
  • 使用自定义排序函数 sort((a, b) => a - b) 非常快。使用类型化数组的唯一好处是在处理大型数组时,它不支持动态大小或推送,并且实例化数组也比 [] 花费更多时间,因此这一切都取决于使用情况。我想说,如果您处理的元素数组少于 20k,则不必担心类型化数组。 (2认同)

R.M*_*eza 22

上升

arr.sort((a, b) => a - b);
Run Code Online (Sandbox Code Playgroud)

降序

arr.sort((a, b) => b - a);
Run Code Online (Sandbox Code Playgroud)

只是为了好玩:

降序 = 升序 + 反向

arr.sort((a, b) => a - b).reverse();
Run Code Online (Sandbox Code Playgroud)


Bla*_*ack 21

sort函数表现得如此奇怪的原因

文档:

[...]根据每个元素的字符串转换,根据每个字符的Unicode代码点值对数组进行排序.

如果打印数组的unicode点值,那么它将变得清晰.

console.log("140000".charCodeAt(0));
console.log("104".charCodeAt(0));
console.log("99".charCodeAt(0));

//Note that we only look at the first index of the number "charCodeAt(  0  )"
Run Code Online (Sandbox Code Playgroud)

返回:"49,49,57".

49 (unicode value of first number at 140000)
49 (unicode value of first number at 104)
57 (unicode value of first number at 99)
Run Code Online (Sandbox Code Playgroud)

现在,因为140000和104返回相同的值(49),它会切断第一个索引并再次检查:

console.log("40000".charCodeAt(0));
console.log("04".charCodeAt(0));

//Note that we only look at the first index of the number "charCodeAt(  0  )"
Run Code Online (Sandbox Code Playgroud)

52 (unicode value of first number at 40000)
40 (unicode value of first number at 04)
Run Code Online (Sandbox Code Playgroud)

如果我们对此进行排序,那么我们将获得:

40 (unicode value of first number at 04)
52 (unicode value of first number at 40000)
Run Code Online (Sandbox Code Playgroud)

所以104在140000之前.

所以最终结果将是:

var numArray = [140000, 104, 99];
numArray = numArray.sort();
console.log(numArray)
Run Code Online (Sandbox Code Playgroud)

104, 140000, 99

结论:

sort()仅通过查看数字的第一个索引进行排序.sort()并不关心整数是否大于另一个,它比较数字的unicode值,如果有两个相等的unicode值,则检查是否有下一个数字并进行比较.

要正确排序,您必须将比较函数传递给此处sort()说明的内容.


小智 17

我同意aks,但不是使用

return a - b;
Run Code Online (Sandbox Code Playgroud)

你应该用

return a > b ? 1 : a < b ? -1 : 0;
Run Code Online (Sandbox Code Playgroud)

  • 而a - b不是吗? (21认同)
  • 你能解释为什么有人_should_使用你更难以理解的三元手术吗?据我所知,它会有相同的结果. (17认同)
  • "return ab"可能适用于这个问题的特定情况(javascript,以及所有已知为int的输入项),但我个人更喜欢三元形式,因为它更规范 - 它适用于更多情况,更多编程语言,具有更多数据类型.例如,在C中,ab可以溢出,导致无限循环,破坏内存,崩溃等等.也就是说,如果涉及NaN或混合类型,即使是三元形式也无法正常工作. (12认同)
  • `>`和`<`仍将a和b作为字符串进行比较. (8认同)
  • 这个答案也考虑了相同的值,并将它们放在同一个地方. (6认同)
  • @stefannew有一种情况,这个答案会返回对'a - b`没有的数字的正确评价.其中`a = b = -Infinity`,`a - b = NaN`,但三元返回'0`.但这似乎并没有影响排序,它仍然完美.`(a> b) - (a <b)`是一个相当于这个三元的较短版本. (4认同)

San*_*nde 17

Array.sort默认情况下使用字母排序而不是数字排序。

要支持数字,请添加如下内容

var numArray = [140000, 104, 99];
numArray.sort((a, b) =>  a - b); // <-- Ascending
numArray.sort((a, b) =>  b - a); // <-- Descending
console.log(numArray);
Run Code Online (Sandbox Code Playgroud)

输出 :

数组数值排序


小智 10

在JavaScript中,sort()方法的默认行为是按字母顺序对数组中的值进行排序.

要按数字排序,您必须定义数字排序函数(这非常简单):

...
function sortNumber(a, b)
{
  return a - b;
}

numArray = numArray.sort(sortNumber);
Run Code Online (Sandbox Code Playgroud)


Cha*_*ait 9

在新的ES6世界中,它更容易进行排序

numArray.sort((a,b) => a-b);
Run Code Online (Sandbox Code Playgroud)

多数民众赞成你需要:)


Mer*_*Joe 8

Array.prototype.sort()是用于排序数组的方法,但是我们需要注意一些问题.

无论数组中的值类型如何,排序顺序都是默认的词典,而不是数字.即使数组是所有数字,所有值都将转换为字符串并按字典顺序排序.

那么我们是否需要自定义sort()和reverse()方法,如下所示.

推荐的网址

用于排序数组内的数字

numArray.sort(function(a, b)
{
    return a - b;
});
Run Code Online (Sandbox Code Playgroud)

用于反转数组内的数字

numArray.sort(function(a, b)
{
    return b - a;
});
Run Code Online (Sandbox Code Playgroud)

推荐的网址


Com*_*ide 6

问题已经回答,最短的方法就是使用sort()方法。但是,如果您正在寻找更多方式对数字数组进行排序,并且您也喜欢循环,请检查以下内容

插入排序

上升:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
    var target = numArray[i];
    for (var j = i - 1; j >= 0 && (numArray[j] > target); j--) {
        numArray[j+1] = numArray[j];
    }
    numArray[j+1] = target
}
console.log(numArray);
Run Code Online (Sandbox Code Playgroud)

降序:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
    var target = numArray[i];
    for (var j = i - 1; j >= 0 && (numArray[j] < target); j--) {
        numArray[j+1] = numArray[j];
    }
    numArray[j+1] = target
}
console.log(numArray);
Run Code Online (Sandbox Code Playgroud)

选择排序:

上升:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
    var min = i;
    for (var j = i + 1; j < numArray.length; j++) {
        if (numArray[j] < numArray[min]) {
            min = j;
        }
    }
    if (min != i) {
        var target = numArray[i];
        numArray[i] = numArray[min];
        numArray[min] = target;
    }
}
console.log(numArray);
Run Code Online (Sandbox Code Playgroud)

降序:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
    var min = i;
    for (var j = i + 1; j < numArray.length; j++) {
        if (numArray[j] > numArray[min]) {
            min = j;
        }
    }
    if (min != i) {
        var target = numArray[i];
        numArray[i] = numArray[min];
        numArray[min] = target;
    }
}
console.log(numArray);
Run Code Online (Sandbox Code Playgroud)

玩得开心


Ali*_*sro 6

处理 undefined、null 和 NaN:Null 的行为类似于 0、NaN 和 undefined 结束。

array = [3, 5, -1, 1, NaN, 6, undefined, 2, null]
array.sort((a,b) => isNaN(a) || a-b)
// [-1, null, 1, 2, 3, 5, 6, NaN, undefined]
Run Code Online (Sandbox Code Playgroud)


lee*_*101 5

当作为回调函数提供时,下面的“按数字”功能可用于对数字数组进行数字排序:

function numerically(a, b){
    return a-b;
}

array.sort(numerically); 
Run Code Online (Sandbox Code Playgroud)

但是在某些罕见的情况下,数组包含非常大的负数,由于ab的结果小于JavaScript可以处理的最小数,所以会发生溢出错误。

因此,编写数字函数的更好方法如下:

function numerically(a, b){
   if(a < b){
      return -1;
   } else if(a > b){
      return 1;
   } else {
      return 0;
   }
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*llo 5

numArray.sort((a,b) => a - b)当数组仅包含没有无穷大或 NaN 的数字时,接受的答案和等价物就很好。它们可以扩展为处理无穷大和 NaN,如下所示:

numArray.sort((a,b) => (+a || 0) - (+b || 0) || 0);
Run Code Online (Sandbox Code Playgroud)

这会将 NaN(或任何非数字,如 'foo' 或 {})视为 0 进行排序。|| 0需要使用 Final 来处理 a 和 b 相等无穷大的情况。