【问题标题】:How to sort an array of integers correctly如何正确排序整数数组
【发布时间】:2021-12-04 13:10:08
【问题描述】:

试图从一个我知道只包含整数的数组中获取最大值和最小值似乎比我想象的要难。

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

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

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

【问题讨论】:

  • 顺便说一句,如果您要对 很多 个整数进行排序,那么使用像 counting sort 这样的整数排序算法会更有优势。时间计数排序将与数组大小成线性关系:O(n)。而这里的所有解决方案都使用效率较低的比较排序:O(n * log n)。
  • @Web_Designer 计数排序对于数字范围是线性的,而不是数组。例如,排序 [1,1000000] 将需要超过 2 个步骤,因为该算法必须扫描 1 到 1000000 之间的每个数组索引以查看哪个单元格的值大于 0。
  • @yters 使用哈希图,您可以只关注正在排序的数组中出现的整数。这使得排序与数组大小成线性关系。
  • 最快的方法是使用同构的sort-array 模块,它可以在浏览器和节点中本地工作,支持任何类型的输入、计算字段和自定义排序顺序。
  • @Quuxplusone 这个问题是关于数字排序的,NaN 不是数字。处理 NaN 仅在您希望有 NaN 的情况下相关,这是我们有一组数字的情况的一小部分。

标签: javascript arrays sorting numbers


【解决方案1】:

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

var numArray = [140000, 104, 99];
numArray.sort(function(a, b) {
  return a - b;
});

console.log(numArray);

文档:

Mozilla Array.prototype.sort() 建议对不包含 Infinity 或 NaN 的数组使用此比较函数。 (因为Infinity - Infinity 是 NaN,而不是 0)。

还有按键排序对象的示例。

【讨论】:

  • 不错。但是真的没有开箱即用的方法可以从 javascript 中获取数字排序吗?
  • 啊,这是开箱即用的!但是如果你真的不切实际,你可以在你的 JavaScript 的最开始将函数绑定到数组类类: // Array.prototype.sortNormal = function(){return this.sort(function(a,b){return a - b})} // 现在在任何数组上调用 .sortNormal() 都会对其进行数字排序
  • 为什么是 a-b 而不是 a>b。为了避免操作机器出错,我建议最后一个
  • @Velthune 比较函数应返回 -1、0 或 +1。 a>b 只会返回 true 或 false。
  • 此代码可以使用Arrow Function 缩短。 numberArray.sort((a, b) => (a - b));耶!我认为这接近于开箱即用的方式。 注意:检查你的 JS 引擎是否支持箭头函数。
【解决方案2】:

在上述所有答案的基础上,它们也可以像这样在一行中完成:

var numArray = [140000, 104, 99];
numArray = numArray.sort(function (a, b) {  return a - b;  });

//outputs: 99, 104, 140000

【讨论】:

  • 我认为你的意思是一种表达方式。
  • @bodyflex 固定:var arr = [140000, 104, 99].sort(function(a,b) { return a-b; });。或者更紧凑,在 ES6 中 let arr = [140000, 104, 99].sort((a,b) => a-b);
【解决方案3】:

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

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

var numArray = new Float64Array([140000, 104, 99]);
numArray = numArray.sort();
console.log(numArray)

【讨论】:

  • 使用 TypedArray 将排序速度提高了大约 5 倍。如果你想跑得更快 hpc-algorithms npm 包实现了基数排序和计数排序,这里有几个答案建议。
  • 我用负数试了一下,结果很奇怪:> new Uint32Array([ -4, -7, 1, 4 ]).sort() 返回了Uint32Array(4) [ 1, 4, 4294967289, 4294967292 ]
  • @Nikolay D 那些是未签名的。您可以使用 Int32Array。
  • 确保对类型化数组进行排序更快。但是如果你有一个常规数组,将它转换为类型化数组来排序并不是一个好的解决方案(速度和内存)
  • @Gio 不确定这是真的。内存需求仅为 O(2n),对于数百万个项目的数组来说,这只有几兆字节。至于速度 - 将数组转换为 typedarray,排序和转换回来仍然比使用函数对数组进行排序更快。
【解决方案4】:

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

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

numArray.sort(compareNumbers);

另请注意,排序“就地”工作,不需要分配。

【讨论】:

  • 上面的代码没看懂,"return a - b"是怎么升序排序的?
  • 如果 a b,则为正。如果相等,则返回 0。
  • @AliMertCakar 因为它只返回真或假,比较函数需要返回负数、零或正数。
【解决方案5】:

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

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

most browsers today支持。

【讨论】:

    【解决方案6】:

    排序函数表现如此怪异的原因

    来自documentation

    [...] 数组根据每个字符的 Unicode 码位排序 值,根据每个元素的字符串转换。

    如果你打印数组的unicode point values 那么它就会变得清晰。

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

    这将返回:“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)
    

    现在,因为 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  )"
    52 (unicode value of first number at 40000)
    40 (unicode value of first number at 04)
    

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

    40 (unicode value of first number at 04)
    52 (unicode value of first number at 40000)
    

    所以 104 在 140000 之前。

    所以最终结果将是:

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

    104, 140000, 99

    结论:

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

    要正确排序,您必须将比较函数传递给sort(),就像here 解释的那样。

    【讨论】:

    • 提示:这只是我的解释,我并没有实际查找代码。所以不要完全相信这个答案。
    【解决方案7】:

    我同意 aks,但是不要使用

    return a - b;
    

    你应该使用

    return a > b ? 1 : a < b ? -1 : 0;
    

    【讨论】:

    • 你能解释一下为什么有人应该使用你更不可读的三元运算吗?据我所知,它会产生相同的结果。
    • 这个答案也考虑了相等的值并将它们留在同一个地方。
    • "return ab" 可能足以解决这个问题的特定情况(javascript,以及所有已知为整数的输入项),但我个人更喜欢三元形式,因为它更规范——它有效在更多的情况下,在更多的编程语言中,具有更多的数据类型。例如。在 C 中,a-b 可能会溢出,导致排序无限循环、破坏内存、崩溃等。也就是说,如果涉及 NaN 或混合类型,即使三元形式也无法正常工作。
    • &gt;&lt; 仍然将 a 和 b 作为字符串进行比较。
    • @stefannew 在一种情况下,此答案会返回对 a - b 没有的数字的正确评估。其中a = b = -Infinitya - b = NaN,但三元返回0。但这似乎并没有影响排序,它仍然可以完美地完成。 (a &gt; b) - (a &lt; b) 是一个较短的版本,相当于这个三元。
    【解决方案8】:

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

    要按数字排序,您必须定义一个数字排序函数(这很简单):

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

    【讨论】:

      【解决方案9】:

      只做.sort((a, b) =&gt; a - b) 而不是.sort() 本身

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

      【讨论】:

      • 非常有帮助!
      【解决方案10】:

      Array.prototype.sort() 是对数组进行排序的 go to 方法,但我们需要注意几个问题。

      无论数组中的值类型如何,默认情况下排序顺序都是字典顺序的,而不是数字的。即使数组全是数字,所有的值都会被转换成字符串并按字典顺序排序。

      那么我们是否需要像下面这样自定义 sort() 和 reverse() 方法。

      Referred URL

      用于对数组内的数字进行排序

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

      用于反转数组内的数字

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

      Referred URL

      【讨论】:

        【解决方案11】:

        问题已经回答了,最快捷的方法是使用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);

        降序:

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

        选择排序:

        升序:

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

        降序:

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

        玩得开心

        【讨论】:

        • 对于微型数组,这些中的任何一个实际上是否比在像 this answer suggests 这样的 TypedArray 上使用 sort() 更快。当然,对于大中型数组,它们不会更快,因为它们是 O(n^2) 算法。
        【解决方案12】:

        升序

        arr.sort((a, b) => a - b);
        

        降序

        arr.sort((a, b) => b - a);
        

        只是为了好玩:

        降序 = 升序 + 逆序

        arr.sort((a, b) => a - b).reverse();
        

        【讨论】:

          【解决方案13】:

          当作为回调函数提供时,下面的函数“numerically”在许多情况下用于对数字数组进行数字排序:

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

          但在极少数情况下,当数组包含非常大的负数时,可能会发生溢出错误,因为 a-b 的结果小于 JavaScript 可以处理的最小数字。

          所以一个更好的数值函数写法如下:

          function numerically(a, b){
             if(a < b){
                return -1;
             } else if(a > b){
                return 1;
             } else {
                return 0;
             }
          }
          

          【讨论】:

          • JavaScript 数字是浮点数。 IEEE754 定义了上溢和下溢规则,包括上溢到+-Infinity,下溢到subnormal 或+-0.0。我认为两个数字的减法不会下溢到 +-0.0,即使它们都很大并且接近相等。两个双精度值之间的差异始终可以表示为另一个非零双精度值(除非它溢出,如 DBL_MIN - DBL_MAX),但下溢是不可能的。灾难性取消使结果不精确,丢失了大部分“有效数字”,但 a-b 将始终为非零,并且具有正确的 a!=b 符号。
          【解决方案14】:

          处理 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]
          

          【讨论】:

          • 语言规范要求比较函数在数组的任意两个元素上调用时始终返回 NaN 以外的数字。此函数在 b 为 NaN 或未定义且 a 和 b 均为 Infinity 或均为 -Infinity 时返回 NaN。
          • 检查 NaN 的想法还不错,但是这段代码并没有把 NaN 放在最后
          【解决方案15】:

          虽然在 JavaScript 中不需要,但如果您希望 sort() compareFunction 严格返回 -1、0 或 1(类似于 spaceship operator 在 PHP 中的工作方式),那么您可以使用 Math.sign() .

          下面的compareFunction 严格返回-1、0 或1:

          numArray.sort((a, b) => Math.sign(a - b));
          

          注意:Math.sign() 在 Internet Explorer 中不受支持。

          【讨论】:

            【解决方案16】:

            仅适用于普通的元素值数组:

            function sortArrayOfElements(arrayToSort) {
                function compareElements(a, b) {
                    if (a < b)
                        return -1;
                    if (a > b)
                        return 1;
                    return 0;
                }
            
                return arrayToSort.sort(compareElements);
            }
            
            e.g. 1:
            var array1 = [1,2,545,676,64,2,24]
            **output : [1, 2, 2, 24, 64, 545, 676]**
            
            var array2 = ["v","a",545,676,64,2,"24"]
            **output: ["a", "v", 2, "24", 64, 545, 676]**
            

            对于对象数组:

            function sortArrayOfObjects(arrayToSort, key) {
                function compareObjects(a, b) {
                    if (a[key] < b[key])
                        return -1;
                    if (a[key] > b[key])
                        return 1;
                    return 0;
                }
            
                return arrayToSort.sort(compareObjects);
            }
            
            e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]
            
            **output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]**
            

            【讨论】:

              【解决方案17】:

              更新!滚动到答案底部以获取 smartSort 道具添加剂,这会带来更多乐趣!
              任何东西的数组进行排序!

              我个人最喜欢的这个函数形式允许使用升序或降序参数:

              function intArraySort(c, a) {
                  function d(a, b) { return b - a; }
                  "string" == typeof a && a.toLowerCase();
                  switch (a) {
                      default: return c.sort(function(a, b) { return a - b; });
                      case 1:
                              case "d":
                              case "dc":
                              case "desc":
                              return c.sort(d)
                  }
              };
              

              用法简单如下:

              var ara = function getArray() {
                      var a = Math.floor(Math.random()*50)+1, b = [];
                      for (i=0;i<=a;i++) b.push(Math.floor(Math.random()*50)+1);
                      return b;
                  }();
              
              //    Ascending
              intArraySort(ara);
              console.log(ara);
              
              //    Descending
              intArraySort(ara, 1);
              console.log(ara);
              
              //    Ascending
              intArraySort(ara, 'a');
              console.log(ara);
              
              //    Descending
              intArraySort(ara, 'dc');
              console.log(ara);
              
              //    Ascending
              intArraySort(ara, 'asc');
              console.log(ara);
              

              jsFiddle


              或此处的代码片段示例!

              function intArraySort(c, a) {
              	function d(a, b) { return b - a }
              	"string" == typeof a && a.toLowerCase();
              	switch (a) {
              		default: return c.sort(function(a, b) { return a - b });
              		case 1:
              		case "d":
              		case "dc":
              		case "desc":
              		return c.sort(d)
              	}
              };
              
              function tableExample() {
              	var d = function() {
              			var a = Math.floor(50 * Math.random()) + 1,
              				b = [];
              			for (i = 0; i <= a; i++) b.push(Math.floor(50 * Math.random()) + 1);
              			return b
              		},
              		a = function(a) {
              			var b = $("<tr/>"),
              				c = $("<th/>").prependTo(b);
              			$("<td/>", {
              				text: intArraySort(d(), a).join(", ")
              			}).appendTo(b);
              			switch (a) {
              				case 1:
              				case "d":
              				case "dc":
              				case "desc":
              					c.addClass("desc").text("Descending");
              					break;
              				default:
              					c.addClass("asc").text("Ascending")
              			}
              			return b
              		};
              	return $("tbody").empty().append(a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1))
              };
              
              tableExample();
              table { border-collapse: collapse; }
              th, td { border: 1px solid; padding: .25em .5em; vertical-align: top; }
              .asc { color: red; }
              .desc { color: blue }
              <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
              <table><tbody></tbody></table>

              .smartSort('asc' | 'desc')

              现在,使用对包含多个项目的数组进行排序的排序方法获得更多乐趣!目前不涵盖“关联”(又名字符串键),但它确实涵盖了每种类型的值!它不仅会相应地对多个值ascdesc 进行排序,而且还会保持值“组”的恒定“位置”。换一种说法;整数总是首先出现,然后是字符串,然后是数组(是的,我正在制作这个多维的!),然后是对象(未过滤,元素,日期),最后是未定义和空值!

              “为什么?”你问。为什么不呢!

              现在有两种口味!第一个需要更新的浏览器,因为它使用Object.defineProperty 将方法添加到Array.protoype 对象。这使得 自然 使用变得容易,例如:myArray.smartSort('a')。如果您需要为旧版浏览器实现,或者您只是不喜欢修改原生对象,请向下滚动到 Method Only 版本。

              /* begin */
              /* KEY NOTE! Requires EcmaScript 5.1 (not compatible with older browsers) */
              ;;(function(){if(Object.defineProperty&&!Array.prototype.smartSort){var h=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a>b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("a");b instanceof Array&&b.smartSort("a");if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("a"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("a"),a.id==e[0]?1:-1;e=[a.tagName, b.tagName].smartSort("a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("a"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d"); return a[d].tagName==c[0]?1:-1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]>g[1]},k=function(a,b){if(null== a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("d");b instanceof Array&&b.smartSort("d");if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("d"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("d"),a.id==e[0]?-1:1;e=[a.tagName,b.tagName].smartSort("d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("d"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1;if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]};Object.defineProperty(Array.prototype,"smartSort",{value:function(){return arguments&& (!arguments.length||1==arguments.length&&/^a([sc]{2})?$|^d([esc]{3})?$/i.test(arguments[0]))?this.sort(!arguments.length||/^a([sc]{2})?$/i.test(arguments[0])?h:k):this.sort()}})}})();
              /* end */
              

              jsFiddle Array.prototype.smartSort('asc|desc')


              使用很简单!首先制作一些疯狂的数组,例如:

              window.z = [ 'one', undefined, $('<span />'), 'two', null, 2, $('<div />', { id: 'Thing' }), $('<div />'), 4, $('<header />') ];
              z.push(new Date('1/01/2011'));
              z.push('three');
              z.push(undefined);
              z.push([ 'one', 'three', 'four' ]);
              z.push([ 'one', 'three', 'five' ]);
              z.push({ a: 'a', b: 'b' });
              z.push({ name: 'bob', value: 'bill' });
              z.push(new Date());
              z.push({ john: 'jill', jack: 'june' });
              z.push([ 'abc', 'def', [ 'abc', 'def', 'cba' ], [ 'cba', 'def', 'bca' ], 'cba' ]);
              z.push([ 'cba', 'def', 'bca' ]);
              z.push({ a: 'a', b: 'b', c: 'c' });
              z.push({ a: 'a', b: 'b', c: 'd' });
              

              然后简单地排序!

              z.smartSort('asc'); // Ascending
              z.smartSort('desc'); // Descending
              

              仅方法

              同上,只是一个简单的方法!

              /* begin */
              /* KEY NOTE! Method `smartSort` is appended to native `window` for global use. If you'd prefer a more local scope, simple change `window.smartSort` to `var smartSort` and place inside your class/method */
              window.smartSort=function(){if(arguments){var a,b,c;for(c in arguments)arguments[c]instanceof Array&&(a=arguments[c],void 0==b&&(b="a")),"string"==typeof arguments[c]&&(b=/^a([sc]{2})?$/i.test(arguments[c])?"a":"d");if(a instanceof Array)return a.sort("a"==b?smartSort.asc:smartSort.desc)}return this.sort()};smartSort.asc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a> b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.asc);b instanceof Array&&b.sort(smartSort.asc);if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c], b[c]],"a"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"a"),a.id==e[0]?1:-1;e=smartSort([a.tagName,b.tagName],"a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g), "a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"a"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"a");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1; if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==c[0]?1:-1}g=[a,b].sort();return g[0]>g[1]};smartSort.desc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)? 1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.desc);b instanceof Array&&b.sort(smartSort.desc);if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c],b[c]],"d"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]], b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"d"),a.id==e[0]?-1:1;e=smartSort([a.tagName,b.tagName],"d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g),"a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&& b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"d"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1; if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]}
              /* end */
              

              用途:

              z = smartSort(z, 'asc'); // Ascending
              z = smartSort(z, 'desc'); // Descending
              

              jsFiddle Method smartSort(Array, "asc|desc")

              【讨论】:

                【解决方案18】:

                试试这个代码:

                HTML:

                <div id="demo"></div>
                

                JavaScript 代码:

                <script>
                    (function(){
                        var points = [40, 100, 1, 5, 25, 10];
                        document.getElementById("demo").innerHTML = points;
                        points.sort(function(a, b){return a-b});
                        document.getElementById("demo").innerHTML = points;
                    })();
                </script>
                

                【讨论】:

                  【解决方案19】:

                  试试下面的代码

                  var a = [5, 17, 29, 48, 64, 21];
                  function sortA(arr) {
                  return arr.sort(function(a, b) {
                  return a - b;
                  })
                  ;} 
                  alert(sortA(a));
                  

                  【讨论】:

                    【解决方案20】:

                    TypeScript 变体

                    const compareNumbers = (a: number, b: number): number => a - b
                    
                    myArray.sort(compareNumbers)
                    

                    【讨论】:

                      【解决方案21】:

                      为了创建这种排序,您必须传递一个检查哪个先出现的函数。

                      在函数内部定义你想检查哪个值:a.id - a.id

                              const myJson = [
                                  { id: 1, name: 'one'},
                                  { id: 4, name: 'four'},
                                  { id: 2, name: 'two'},
                                  { id: 3, name: 'three'}
                              ];
                      
                              // provide the sort method to check
                              const myNewSort = myJson.sort(function(a, b) {
                                return a.id - b.id;
                              });
                      
                              console.log('my new sort',myNewSort)

                      【讨论】:

                        【解决方案22】:

                        排序混合

                        Object.defineProperty(Array.prototype,"sort_mixed",{
                            value: function () { // do not use arrow function
                                var N = [], L = [];
                                this.forEach(e => {
                                    Number.isFinite(e) ? N.push(e) : L.push(e);
                                });
                                N.sort((a, b) => a - b);
                                L.sort();
                                [...N, ...L].forEach((v, i) => this[i] = v);
                                return this;
                            })
                        

                        试试a =[1,'u',"V",10,4,"c","A"].sort_mixed(); console.log(a)

                        【讨论】:

                          【解决方案23】:

                          如果有人不明白 Array.sort() 如何处理整数,请阅读此答案。

                          字母顺序

                          默认情况下,sort() 方法按字母和升序将值排序为字符串。

                          const myArray = [104, 140000, 99];
                          myArray.sort();
                          console.log(myArray); // output is [104, 140000, 99]
                          

                          升序与array.sort(compareFunction)

                          const myArray = [104, 140000, 99];
                          myArray.sort(function(a, b){
                            return a - b;
                          });
                          console.log(myArray); // output is [99, 104, 140000]
                          

                          来自w3schools的解释:

                          compareFunction 定义了另一种排序顺序。该函数应返回负值、零值或正值,具体取决于参数,例如: 函数(a,b){返回 a-b} 当 sort() 方法比较两个值时,会将值发送给 compare 函数,并根据返回的(负、零、正)值对值进行排序。

                          例子:

                          比较 40 和 100 时,sort() 方法调用 compare 函数(40,100)。

                          函数计算40-100,返回-60(负值)。

                          排序函数会将 40 排序为小于 100 的值。

                          降序使用array.sort(compareFunction)

                          const myArray = [104, 140000, 99];
                          myArray.sort(function(a, b){
                            return b - a;
                          });
                          console.log(myArray); // output is [140000, 104, 99]
                          

                          这次我们用b - a(即100-40)计算,返回一个正值。

                          【讨论】:

                            【解决方案24】:

                            您可以简单地使用 ma​​x()min() 内置函数来获得高度和最低数字

                            var numArray = [140000, 104, 99];
                            console.log(Math.max(...numArray));
                            console.log(Math.min(...numArray));
                            

                            如果要按升序或降序排序

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

                            Know more

                            【讨论】:

                              【解决方案25】:

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

                              numArray.sort((a,b) => (+a || 0) - (+b || 0) || 0);
                              

                              这会将 NaN(或任何非数字,如 'foo' 或 {})排序为 0。最后的 || 0 用于处理 a 和 b 相等无穷大的情况。

                              【讨论】:

                                【解决方案26】:

                                如果您需要从字符串列表中计算和排序最大的 charCodeAt,这是正确的方法。

                                const arrayLines = '1.1.1.1\n1.0.1.1\n1.1.1.2\n1.1.1.0'.split('\n');
                                
                                // Response: (4) ['1.0.1.1', '1.1.1.0', '1.1.1.1', '1.1.1.2']
                                arrayLines.sort((a, b) => {
                                    let a_charCodeSize = 0,
                                        b_charCodeSize = 0;
                                
                                    // Loop true a & b characters and calculate the charCodeAt size.
                                    for (const aChar of a) a_charCodeSize += aChar.charCodeAt(0);
                                    for (const bChar of b) b_charCodeSize += bChar.charCodeAt(0);
                                
                                    return a_charCodeSize - b_charCodeSize;
                                });
                                

                                【讨论】:

                                • 为什么需要编写任何实现,javascript sort 本机做完全相同的事情,它从起始索引通过字符代码比较字符串并向前移动。 arrayLines.sort() 以相同的方式响应,不传递任何自定义函数
                                • @SajidAli 原生排序不会一一比较所有字符,而是评估给定的整个值。在那种情况下,这不会导致正确的响应。
                                • 在上面的例子中尝试原生排序,看看...... sort() 对数组的元素进行就地排序并返回排序后的数组。默认排序顺序是升序,基于将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列 如果未提供函数,则通过将所有未定义的数组元素转换为字符串并比较 UTF- 16 个代码单元订购。例如,“香蕉”出现在“樱桃”之前。在数字排序中,9 在 80 之前,但由于数字被转换为字符串,因此在 Unicode 顺序中,“80”在“9”之前。参考:MDN
                                • @SajidAli 我试过了,但它没有产生所需的输出。使用 a-b 排序返回 ['1.1.1.1', '1.0.1.1', '1.1.1.2', '1.1.1.0'] 没有意义。
                                【解决方案27】:

                                由于 sort 方法将 Array 元素转换为字符串。因此,以下方式也适用于带有数组元素的十进制数。

                                let productPrices = [10.33, 2.55, 1.06, 5.77];
                                console.log(productPrices.sort((a,b)=>a-b));
                                

                                并为您提供预期的结果。

                                【讨论】:

                                • “因为 sort 方法将 Array 元素转换为字符串。” — 不,它没有。
                                【解决方案28】:

                                对大于 0 的整数进行排序,跳出框框思考:

                                function sortArray(arr) {
                                  return new Promise((resolve) => {
                                    const result = []
                                    arr.forEach((item) => {
                                      setTimeout(() => {
                                        result.push(item)
                                        if (result.length === arr.length) resolve(result)
                                      }, item)
                                    })
                                  })
                                }
                                
                                sortArray([4, 2, 42, 128, 56, 2]).then((result) => {
                                  document.write(JSON.stringify(result))
                                })

                                请注意,这不应该有效地使用,.sort() 更适合这个,检查其他答案

                                【讨论】:

                                  【解决方案29】:

                                  您可以简单地对数字数组进行排序

                                  const num=[13,17,14,19,16];
                                  let temp;
                                  for(let i=0;i<num.length;i++){
                                      for(let j=i+1;j<num.length;j++){
                                          if(num[i]>num[j]){
                                              temp=num[i]
                                              num[i]=num[j]
                                              num[j]=temp
                                          }
                                      }
                                  }
                                  
                                  console.log(num);

                                  【讨论】:

                                    【解决方案30】:
                                    1. 升序

                                      常量移动 = [200, 450, -400, 3000, -650, -130, 70, 1300];

                                    如果我们返回

                                     movements.sort((a, b) => {
                                          if (a > b) return 1; //- (Switch order)
                                          if (a < b) return -1; //- (Keep order)
                                        });
                                    

                                    a - 当前值,b - 下一个值。

                                    1. 降序

                                      movements.sort((a, b) => { 如果 (a > b) 返回 -1; // - (保持) 如果 (a

                                    !改进,最好的解决方案!

                                    movements.sort ((a, b) => a - b); // Same result!
                                    

                                    如果 a

                                    【讨论】:

                                    • 您的最后一位有错字,导致矛盾。您的第一位没有解决 a==b 的情况。要格式化内联代码,请用单个反引号将其包围。
                                    猜你喜欢
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多