尝试从我知道仅包含整数的数组中获取最高和最低值似乎比我想象的要难。



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




我希望它显示99, 104, 140000。而是显示104, 140000, 99。因此,似乎排序是将值作为字符串处理。
是否有一种方法可以使sort函数实际对整数值进行排序?

评论

注意,最重要的答案中没有一个正确地处理所有浮点值。特别是它们都不处理NaN。看到有关NaN的排名靠前的答案真是太好了。

顺便说一句,如果您要对很多整数进行排序,那么使用整数排序算法(如计数排序)将是有利的。时间计数排序将根据数组的大小O(n)线性运行刻度。此处所有解决方案都使用效率较低的比较排序:O(n * log n)。

@Web_Designer计数排序是线性的,关于数字范围,而不是数组。例如,对[1,1000000]进行排序将需要2个以上的步骤,因为该算法将必须扫描1到1000000之间的每个数组索引以查看哪个单元格的值大于0。

@yters使用哈希图,您只能注意排序数组中显示的整数。这样可使排序线性化为数组大小。

最快的方法是使用同构排序数组模块,该模块可在浏览器和节点中本机运行,支持任何类型的输入,计算字段和自定义排序顺序。

#1 楼

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




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

console.log(numArray); 





在ES6中,您可以使用箭头功能简化此操作:

numArray.sort((a, b) => a - b); // For ascending sort
numArray.sort((a, b) => b - a); // For descending sort



文档:

Mozilla Array.prototype.sort()建议此比较功能用于不包含Infinity或NaN的阵列。 (因为Inf - Inf是NaN,而不是0)。

还提供了按键对对象进行排序的示例。

评论


真好但是,实际上没有从javascript中获取数字排序的现成方法吗?

– Peirix
09年6月30日在10:49

啊,这是开箱即用的!但是,如果您确实不切实际,则可以在JavaScript的最开始就将函数绑定到数组类类:// Array.prototype.sortNormal = function(){返回this.sort(function(a,b){返回a -b})} //现在在任何数组上调用.sortNormal()都会对其进行数字排序

–杰克·弗朗岑(Jack Franzen)
13-10-21在1:22



为什么是a-b而不是a> b。我建议最后一个以避免操作机器错误

–路卡·达万佐(Luca Davanzo)
15年4月2日在13:46

@Velthune比较函数应返回-1、0或+1。 a> b将仅返回true或false。

–伊万·佩雷斯(IvánPérez)
2015年9月28日上午10:21

可以使用箭头功能来缩短此代码。 numberArray.sort((a,b)=>(a-b));好极了!我认为这接近开箱即用的方式。注意:请检查您的JS引擎是否支持箭头功能。

–КонстантинВан
2015年12月28日在9:41



#2 楼

只是基于以上所有答案,它们也可以像这样一行完成:

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


评论


@bodyflex固定:var arr = [140000,104,99] .sort(function(a,b){return a-b;});。或更紧凑,在ES6中让arr = [140000,104,99] .sort((a,b)=> a-b);

– 00500005
16年5月17日在16:18



正如我在上面的评论中所说,箭头功能在这里不合适,我不鼓励任何人以这种方式使用它们。您正在使用arrow语法的副作用来切出单词function并返回,但实际上并没有使用arrow function传递此内容的真正目的。这段代码暗示有一些上下文传递发生,但是没有。混淆其他开发人员阅读您的代码,只是节省了一些字符。不要依赖副作用-有目的的代码!

–bambery
16 Dec 2'在5:03

@bambery我认为您不需要为上下文更改专门使用箭头功能…

–特德·莫林(Ted Morin)
17-2-21在20:02



@bambery,您实际上误解了箭头功能的作用。您认为它以某种方式将其传递给函数,但这是不正确的。它实际上忽略了创建this和arguments变量,而这些变量通常会覆盖父变量。可以在箭头函数中使用此命令的唯一原因是词法作用域。

–cuth
17年4月4日在22:07

@bambery的年龄不佳...三年后,现代javascript开发几乎只使用了箭头功能。 :)

–基普
19-10-25在19:32

#3 楼

array.sort默认情况下按字典顺序进行排序,对于数字排序,则提供您自己的功能。这是一个简单的示例:

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

numArray.sort(compareNumbers);


还请注意,排序可以“就地”进行,不需要分配。

评论


我不理解上面的代码,升序如何“返回a-b”?

– vikramvi
19年7月8日在6:58

如果a b,它将为正。如果相等,则返回0。

– Paul Dixon
19年7月8日在14:01

@AliMertCakar,因为它仅返回true或false,并且比较函数需要返回负数,零或正数。

– Paul Dixon
9月28日13:54

#4 楼

我很惊讶为什么每个人都建议将比较器函数传递给sort(),这会使排序真的很慢!
要对数字进行排序,只需创建任何TypedArray:



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




评论


使用TypedArray可使排序速度提高约5倍。如果您想更快一些,hpc-algorithms npm包将实现“基数排序”和“计数排序”,这里有一些答案。

– DragonSpit
19年8月10日在2:26

我用负数尝试了一下,结果却很奇怪:> new Uint32Array([-4,-7,1,4])。sort()返回了Uint32Array(4)[1,4,4294967289,4294967292]。

– Nikolay D
9月5日12:24



@Nikolay D这些未签名。您可以使用Int32Array。

–rion18
9月5日19:07

确保排序类型数组更快。但是,如果您有常规数组,则将其转换为带类型的数组以对其进行排序不是一个好的解决方案(速度和内存)

– Gio
10月30日10:56

@乔不确定这是真的。内存需求仅为O(2n),对于一百万个项目的数组来说,只有几兆字节。至于速度-将数组转换为typedarray,排序和向后转换仍然比使用函数对数组排序更快。

–dy_
10月31日14:20



#5 楼

此答案与某些现有答案相同,但是ECMAScript 6箭头函数提供了更为紧凑的语法,使我们可以在不牺牲可读性的情况下定义内联排序函数:

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


当今大多数浏览器都支持它。

评论


“不牺牲可读性”。这是主观的。使用一些简单的整数,它是可读的。当使用复杂的对象并且您希望对属性进行排序时,不需要太多。

– Tristan
16年2月10日在8:27

@Tristan,仍然可以使用此语法非常干净地对对象的属性进行排序。如果要排序的对象的属性是数字,则可以执行以下操作:objArray = objArray.sort((a,b)=> a.numProperty-b.numProperty);如果该属性是字符串,则可以执行以下操作:objArray = objArray.sort((a,b)=> a.strProperty.localeCompare(b.strProperty))‌话虽如此,这个问题专门询问有关对整数数组进行排序的问题

– jjjjs
16年2月12日在16:28

#6 楼

排序功能如此奇怪的原因

从文档:


[...]根据每个字符的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  )" 





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


so 104在140000之前。

所以最终结果将是:



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





104, 140000, 99

结论:

sort()仅通过查看数字的第一个索引来进行排序。 sort()不在乎整数是否大于整数,它比较数字的unicode的值,并且如果有两个相等的unicode值,则它检查是否存在下一个数字并进行比较。 />
要正确排序,您必须像下面说明的那样将比较函数传递给sort()

评论


提示:这仅是我的解释,我实际上没有查看代码。因此,请不要完全相信这个答案。

–黑色
19年5月31日在9:19

#7 楼

我同意aks,但是不要使用

return a - b;


您应该使用

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


评论


您能解释为什么有人应该使用您更难以理解的三元运算吗?据我所知,它将具有相同的结果。

–stefannew
15年1月16日在17:05

该答案还考虑了相等的值,并将它们放在同一位置。

– Maarten00
15年2月3日在18:57

a-b不是吗?

–布莱恩·雷纳(Bryan Rayner)
2015年2月25日在18:51

“ return ab”对于这个问题的特定情况(javascript,以及所有输入项都是ints)可能就足够了,但是我个人更喜欢三元形式,因为它更规范-在更多情况下,在更多编程语言中都可以使用,具有更多数据类型。例如。在C语言中,a-b可能会溢出,导致无休止的循环,破坏内存,崩溃等。也就是说,如果涉及NaN或混合类型,则即使三元形式也无法正常工作。

–唐·哈奇
2015年12月8日,0:21



>和<仍将a和b比较为字符串。

–vriesdemichael
16年11月18日在11:58

#8 楼

在新的ES6世界中,进行排序要容易得多

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


这就是您所需要的:)

#9 楼

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

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

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

numArray = numArray.sort(sortNumber);


#10 楼

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

默认情况下,排序顺序为字典顺序,而不是数字顺序数组中值的类型。即使数组是全数字,所有值也都将转换为字符串并按字典顺序排序。

因此我们是否需要自定义如下的sort()和reverse()方法。

引用的URL

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

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


用于对数组内的数字求反

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


引用的网址

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





玩得开心

评论


像这样的答案所暗示的那样,对于微型数组而言,这些方法实际上是否比在TypedArray上使用sort()更快?当然,对于中型到大型阵列,它们不会更快,因为它们是O(n ^ 2)算法。

– Peter Cordes
19年11月20日在4:43

#12 楼

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

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

array.sort(numerically); 


但是在某些极少数情况下,其中的数组包含非常大且为负数的数字,由于ab的结果小于JavaScript可以处理的最小数字,因此可能会发生溢出错误。

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

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


评论


JavaScript数字是浮点数。 IEEE754定义了上溢和下溢规则,包括上溢至+ -Infinity和下溢至次标准或+ -0.0。我认为即使两个数字都大且相近,两个数字相减也不会下溢至+ -0.0。两个双精度值之间的差异始终可以表示为另一个非零双精度值(除非它溢出,例如DBL_MIN-DBL_MAX),但不可能发生下溢。灾难性的取消使结果不精确,丢失了大部分“有效数字”,但a-b始终为非零,并具有正确的符号a!= b。

– Peter Cordes
19年11月20日在4:49



#13 楼

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


#14 楼

尽管在JavaScript中不是必需的,但是如果您希望sort() compareFunction严格返回-1、0或1(类似于PHP中的太空船运算符),则可以使用Math.sign()

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

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



注意:Internet Explorer不支持Math.sign()


#15 楼

仅对于普通的元素值数组:

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}]**


#16 楼


更新!滚动到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进行排序,而且还将保持值的“组”的恒定“位置”。换一种说法;整数始终是第一个,然后是字符串,然后是数组(是的,我正在制作多维!),然后是对象(未过滤,元素,日期),最后是undefined和null!

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

现在有2种口味!第一个要求使用较新的浏览器,因为它使用Object.defineProperty将方法添加到Array.protoype对象。这样便于自然使用,例如:myArray.smartSort('a')。如果您需要为较旧的浏览器实现,或者只是不喜欢修改本机对象,请向下滚动至“仅方法”版本。

/* 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方法smartSort(Array,“ asc | desc”)

#17 楼

尝试以下代码:

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>


#18 楼

尝试如下代码

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


评论


是不是?

–user7125929
18年2月12日在13:03

#19 楼

这是已经提出并被接受的解决方案,作为Array原型上的一种方法:

Array.prototype.sortNumeric = function () {
    return this.sort((a, b) => a - b);
};
Array.prototype.sortNumericDesc = function () {
    return this.sort((a, b) => b - a);
};


#20 楼

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


评论


欢迎使用StackOverflow。您的答案与接受的答案相同。您能否在答案中添加任何解释,以说明为什么应优先于接受的答案?

–简·吉德
19年5月22日在4:47

#21 楼

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

#22 楼

如果任何人都不了解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定义了另一个排序顺序。函数应根据参数返回负,零或正值,例如:
function(a,b){return ab}
当sort()方法比较两个值时,它将发送将值添加到compare函数,并根据返回的值(负,零,正)对值进行排序。
示例:
比较40和100时,sort()方法调用compare
function(40,100)。
函数计算40-100,并返回-60(负值)。
sort函数会将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)计算得出了一个正值。

#23 楼

您可以通过

对数字数组进行排序

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




#24 楼

as sort方法将Array元素转换为字符串。因此,下面的方法也可以很好地处理带有数组元素的十进制数字。

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


并给您预期的结果。

评论


“作为一种排序方法,将Array元素转换为字符串。” —不,不是。

–user4642212
7月21日下午2:42

#25 楼

对大于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()更适合此操作,请检查其他答案


#26 楼

这是我在utils库中的排序数组函数:

sortArray: function(array) {
    array.sort(function(a, b) {
        return a > b;
    });
},

# Let's test a string array
var arr = ['bbc', 'chrome', 'aux', 'ext', 'dog'];
utils.sortArray(arr);
console.log(arr);
>>> ["aux", "bbc", "chrome", "dog", "ext", remove: function]

# Let's test a number array
var arr = [55, 22, 1425, 12, 78];
utils.sortArray(arr);
console.log(arr);
>>> [12, 22, 55, 78, 1425, remove: function]


评论


这是完全错误的! sort函数需要返回负数,0或正数,而不是true或false。

– jperelli
16年11月17日在20:57

正如@jperelli所提到的,sort函数需要返回一个数字,而不是布尔值(并给出如何有3种可能的状态,等于,高于和低于,这对于稳定的排序是必要的)。如您的回答所述,它不起作用。应该使用a-b代替。 (您可以看中并执行Number(a> b)-0.5,但这仍然不是一个稳定的排序)。

– ecc521
19年9月17日在0:12