javascript原生排序算法sort(),如果不带排序函数,那么就是默认按照升序排列。如果是数字类型就按照从小到大的顺序排列,如果是字符串,就按照字母顺序排列。
/**
* Sorts an array in place.
* This method mutates the array and returns a reference to the same array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending, ASCII character order.
* ```ts
* [11,2,22,1].sort((a, b) => a - b)
* ```
*/
sort(compareFn?: (a: T, b: T) => number): this;
排序方法定义规定,如果带排序函数(两个参数),并且函数返回负数,一般用-1表示,表示第一个参数小于第二个参数,如果返回0,表示两个参数相等,返回正数,一般用1表示,表示第一个参数大于第二个参数。
从这段描述来看,我们似乎并不清楚,升序排列,降序排列有什么区别?
先来看几个简单的例子:
- var arr = [1,3,4,2]
- console.log(arr)
- arr.sort()
- console.log(arr)
- //==============
- var fruits = ["banana","apple","watermelon","grape","kiwifruit"]
- console.log(fruits)
- fruits.sort()
- console.log(fruits)
- //==============
- var list = ["a_1","a_11","a_2","b_1","b_10","b_3"]
- console.log(list)
- list.sort()
- console.log(list)
'运行
运行结果:
前面两个排序,纯数字和纯字母排序,默认排序是符合我们的期望的。第三个排序,它是一个字母数字的组合,默认只按照字母顺序排列,其实我们期望得到的结果是:
a_1,a_2,a_11,b_1,b_3,b_10
需要这样的排序结果,我们就不能只用默认的排序,我们需要自定义排序规则,我们希望先按照字母排序,字母相同则按照数字排序。这就要求排序需要按照第二个属性来排序,这里虽然是一个字符串数组,完全可以看作一个对象数组,我们不仅需要按照姓名排序,还需要按照序号排序。
我们修改第三个排序:
- var list = ["a_1","a_11","a_2","b_1","b_10","b_3"]
- console.log(list)
- list.sort((a,b)=>{
- var obja = a.split('_')
- var objb = b.split('_')
- var namea = obja[0]
- var nameb = objb[0]
-
- var ida = obja[1]
- var idb = objb[1]
- if(namea==nameb){
- return ida - idb
- }
- return namea - nameb
- })
- console.log(list)
'运行
运行结果:
乍一看,没毛病,正是我们需要的排序。但是我们忽略了一个问题,字符串排序不能直接和数字类型一样做减法。我们在数组中间增加一个元素"c_2",看看结果:
很意外,字母排序好像没有生效。这里namea-nameb其实会做一个隐式转换,直接做减法,而字符串是不能做减法的,所以结果是NaN。并不是前面说的-1,0,1。
他们虽然不能做减法操作,但是却可以比较大小,namea < nameb。但是这种结果返回的是布尔类型(true,false),所以我们还需要做个转换,namea < nameb? -1 :1
还有一种判断方法,就是利用字符串函数localeCompare来比较。这个代码就不贴出来了,大家可以根据下面的截图来感受一下它的作用:
它对字符串作比较,并且返回值正好是-1,0,1三者之一,可以看作是对字符串作比较的一个封装函数。