http://www.f-z.cn/id/212
在实际的业务当中,很多时候要对定义好的数组重新排序。在JavaScript中自带了两个方法,可以对数组进行排序操作。这两个方法就是
sort()
和
reverse()
。今天就来学习这两个方法相关的知识。
sort()方法对数组的元素做原地的排序,并返回这个数组。默认情况下,sort()方法是按升序排列数组项。即最小的值位于最前面,最大的值排列在最后面。为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串,以确定如何排序。
var arr
=
[
'hello'
,
'jame'
,
'Jack'
,
'dog'
]
;
console
.
log
(arr
.
sort
(
)
)
;
正如前面所言,sort()方法未调用任何参数时,是按升序排列的,也就是按字母的顺序排列,所以我们看到结果也是正确的。
var arr
=
[
1
,
5
,
10
,
22
]
;
console
.
log
(arr
.
sort
(
)
)
;
可见,即使示例中数组的顺序没有任何问题,但sort()方法对数组进行重新排序操作之后,顺序反而不对了。这究竟是为何呢?
查了相关文档才知道,sort()方法:如果省略参数,数组项会先根据toString()函数将其值转换成字符串在进行比较,是按UNICODE进行比较的,然后根据这个进行排序。正如最前面的示例,"Jack"会排在"dog"前面。当数字进行排序的时候,"5"会出现在"10"和"22"之后,因为他们先会被转换为字符串,而“10”和“22”都比“5”要靠前。
"Jack"
.
charCodeAt
(
)
==
>
74
"dog"
.
charCodeAt
(
)
==
>
100
"5"
.
charCodeAt
(
)
==
>
53
"10"
.
charCodeAt
(
)
==
>
49
"22"
.
charCodeAt
(
)
==
>
50
如此一来,这不是最佳方案。幸好,sort()方法可以接受一个比较函数compareFunction作为参数,以便我们指定哪个值位于哪个值的前面。
如果指明了compareFunction,那么数组会按照调用该函数的返回值进行排序。比较函数compareFunction接收两个参数a和b,a和b是两个将要被比较的元素:
compareFunction(a,b)返回的值小于0:那么a就小于b,也就是说a排在了b的前面
compareFunction(a,b)返回的值大于0: 那么a就大于b,也就是说a排在了b的后面
compareFunction(a,b)返回的值等于0:那么a就等于b,也就是说a和b的位置保持不变
function compareFunction
(a
, b
)
{
if
(a
< b
)
{
return
-
1
;
}
else
if
(a
> b
)
{
return
1
;
}
else
{
return
0
;
}
}
这个函数可适用于大多数数据类型,只要将compareFunction(a,b)函数作为参数传给sort()方法即可。因到前面的示例:
var arr
=
[
1
,
5
,
10
,
22
]
;
arr
.
sort
(compareFunction
)
;
console
.
log
(arr
)
;
数组arr仍然保持了正确的升序排列。其实可以通过compareFunction(a,b)对数组作降序排列,只需要将compareFunction函数的返回值做个调整即可:
function compareFunction
(a
, b
)
{
if
(a
< b
)
{
return
1
;
}
else
if
(a
> b
)
{
return
-
1
;
}
else
{
return
0
;
}
}
var arr
=
[
1
,
5
,
10
,
22
]
;
arr
.
sort
(compareFunction
)
;
console
.
log
(arr
)
;
注:compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
上面也说到了,sort()方法传入compareFunction(a,b)参数时,返回的值可能有3个,所以下面这样的写法是错误的:
function compareFunction
(a
, b
)
{
return a
< b
;
}
var arr
=
[
21
,
0
,
3
,
11
,
4
,
5
,
6
,
7
,
8
,
9
,
10
]
;
arr
.
sort
(compareFunction
)
;
console
.
log
(arr
)
;
可能得的结果是 [5, 21, 11, 10, 9, 8, 7, 6, 4, 3, 0],这并不是正确的结果,那是因为return a < b只返回了两种值 true或false,相当于1或0,而没有-1。
对于数字类型或valueOf()方法返回数值类型的对象类型,可以使用一个更简单的比较函数。
function ascSort
(a
, b
)
{
return a
- b
;
}
function desSort
(a
, b
)
{
return b
- a
;
}
var arr
=
[
1
,
4
,
10
,
3
]
,
arr2
=
[
100
,
12
,
99
,
3
,
2
]
;
arr
.
sort
(ascSort
)
;
arr2
.
sort
(desSort
)
;
console
.
log
(arr
)
;
console
.
log
(arr2
)
;
创建一个字符串数组,并且使用sort()对字符串进行重新排序:
var stringArray
=
[
'blue'
,
'Humpback'
,
'Beluga'
]
;
stringArray
.
sort
(
)
;
console
.
log
(
'字符串数组stringArray:'
+ stringArray
)
;
字符串数组stringArray
:Beluga
,Humpback
,blue
创建一个数字字符串数组之后对数组进行排序,对比数字数组分别指定与不指定比较函数的结果:
var numericStringArray
=
[
'80'
,
'9'
,
'700'
]
;
function compareFunction
(a
, b
)
{
return a
- b
;
}
console
.
log
(
'不指定比较函数的数字字符串数组排列:'
+ numericStringArray
.
sort
(
)
)
;
console
.
log
(
'指定比较函数的数字字符串数组排列:'
+ numericStringArray
.
sort
(compareFunction
)
)
;
不指定比较函数的数字字符串数组排列:
700
,
80
,
9
指定比较函数的数字字符串数组排列:
9
,
80
,
700
创建一个数字数组之后对数组进行排序,对比数字数组分别指定与不指定比较函数的结果:
var numberArray
=
[
80
,
9
,
700
]
;
function compareFunction
(a
, b
)
{
return a
- b
;
}
console
.
log
(
'不指定比较函数的数字数组排列:'
+ numberArray
.
sort
(
)
)
;
console
.
log
(
'指定比较函数的数字数组排列:'
+ numberArray
.
sort
(compareFunction
)
)
;
不指定比较函数的数字字符串数组排列:
700
,
80
,
9
指定比较函数的数字字符串数组排列:
9
,
80
,
700
创建一个数字和数字字符串混合数组之后进行排序,对比数组分别指定与不指定比较函数的结果:
var mixedNumericArray
=
[
'80'
,
'9'
,
'700'
,
40
,
1
,
5
,
200
]
;
function compareFunction
(a
, b
)
{
return a
- b
;
}
console
.
log
(
'不指定比较函数的数组排列:'
+ mixedNumericArray
.
sort
(
)
)
;
console
.
log
(
'指定比较函数的数组排列'
+ mixedNumericArray
.
sort
(compareFunction
)
)
;
不指定比较函数的数组排列:
1
,
200
,
40
,
5
,
700
,
80
,
9
指定比较函数的数组排列
1
,
5
,
9
,
40
,
80
,
200
,
700
除了给数字数组进行升序或降序排列之外,还可以定义一个随机函数,实现数组的随机排列。定义的随机函数返回正数或者负数,并表将随机函数传给sort()方法,此时sort()方法根据随机函数返回的正负数来决定两个值之前的位置。
var randomArray
=
[
9
,
0
,
23
,
8
,
3
,
5
]
;
function
randomSort
(a
, b
)
{
return Math
.
random
(
)
-
0.5
;
}
console
.
log
(randomArray
.
sort
(randomSort
)
)
;
function
objectSort
(property
, desc
)
{
if
(desc
)
{
return
function
(a
, b
)
{
return
(a
[property
]
> b
[property
]
)
?
-
1
:
(a
[property
]
< b
[property
]
)
?
1
:
0
;
}
}
return
function
(a
, b
)
{
return
(a
[property
]
< b
[property
]
)
?
-
1
:
(a
[property
]
> b
[property
]
)
?
1
:
0
;
}
}
var myArray
=
[
{
"name"
:
"John Doe"
,
"age"
:
29
}
,
{
"name"
:
"Anna Smith"
,
"age"
:
24
}
,
{
"name"
:
"Peter Jones"
,
"age"
:
39
}
]
console
.
log
(myArray
.
sort
(
objectSort
(
'name'
,
true
)
)
)
;
另外,只需要改变比较函数objectSort()中的desc参数值为flase,数组就会按object指定的property属性降序排列:
console
.
log
(myArray
.
sort
(
objectSort
(
'age'
,
false
)
)
)
;
function
dynamicSort
(property
)
{
var sortOrder
=
1
;
if
(property
[
0
]
===
"-"
)
{
sortOrder
=
-
1
;
property
= property
.
substr
(
1
)
;
}
return
function
(a
,b
)
{
var result
=
(a
[property
]
< b
[property
]
)
?
-
1
:
(a
[property
]
> b
[property
]
)
?
1
:
0
;
return result
* sortOrder
;
}
}
console
.
log
(myArray
.
sort
(
dynamicSort
(
'age'
)
)
)
;
console
.
log
(myArray
.
sort
(
dynamicSort
(
'-age'
)
)
)
;
上面介绍的是按一个属性进行排序,但很多时候,希望按多个属性排序,那么比较函数需要做一定的调整:
function
dynamicSortMultiple
(
)
{
var props
= arguments
;
return
function
(obj1
, obj2
)
{
var i
=
0
, result
=
0
, numberOfProperties
= props
.length
;
while
(result
===
0
&& i
< numberOfProperties
)
{
result
=
dynamicSort
(props
[i
]
)
(obj1
, obj2
)
;
i
++
;
}
return result
;
}
}
myArray
.
sort
(
dynamicSortMultiple
(
'name'
,
'-age'
)
)
;
reverse()方法相对而言要简单得多,它就是用来颠倒数组中元素的位置,并返回该数组的引用。比如我们有一个数组:
var myArray
=
[
"Airen"
,
"W3cplus"
,
"Blog"
]
;
console
.
log
(myArray
.
reverse
(
)
)
;
本文主要介绍了数组中元素项的排序方法。而主要详细介绍的是sort()方法。通过给sort()方法传递不同的比较函数,我们可以实现字符串数组、数字数组、数字和数字字符串混合数组、对象数组等按顺序(升序或降序)排列。
学习更多IT知识 加群:272292492