代码改变世界
Posts - 29, Articles - 0, Comments - 62
2014-04-27 19:15 by 那时候的我, 66416 阅读, 2 评论, 收藏, 编辑
js中用方法sort()为数组排序。sort()方法有一个可选参数,是用来确定元素顺序的函数。如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。如:
var arr = ["a", "b", "A", "B"]; arr.sort(); console.log(arr);//["A", "B", "a", "b"]
因为字母A、B的ASCII值分别为65、66,而a、b的值分别为97、98,所以上面输出的结果是 ["A", "B", "a", "b"] 。
如果数组元素是数字呢,结果会是怎样?
var arr = [15, 8, 25, 3]; arr.sort(); console.log(arr);//[15, 25, 3, 8]
结果是 [15, 25, 3, 8] 。其实,sort方法会调用每个数组项的toString()方法,得到字符串,然后再对得到的字符串进行排序。虽然数值15比3大,但在进行字符串比较时"15"则排在"3"前面。显然,这种结果不是我们想要的,这时,sort()方法的参数就起到了作用,我们把这个参数叫做比较函数。
比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个之后则返回一个正数。例子:
var arr = [23, 9, 4, 78, 3]; var compare = function (x, y) {//比较函数 if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } } console.log(arr.sort(compare));
结果为 [3, 4, 9, 23, 78] ,返回了我们想要的结果。如果要按降序排序,比较函数写成这样即可:
var compare = function (x, y) { if (x < y) { return 1; } else if (x > y) { return -1; } else { return 0; } }
我们并不能用比较函数比较一个不能转化为数字的字符串与数字的顺序:
var arr = ["b", 5]; console.log(arr.sort(compare))
结果是 ["b", 5] 。因为比较函数在比较时,会把先把字符串转化为数字,然后再比较,字符串b不能转化为数字,所以就不能比较大小。然而,当不用比较函数时,会比较ASCII值,所以结果是 [5, "b"] 。
如果数组项是对象,我们需要根据数组项的某个属性对数组进行排序,要怎么办呢?其实和前面的比较函数也差不多:
var arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}]; var compare = function (obj1, obj2) { var val1 = obj1.name; var val2 = obj2.name; if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } console.log(arr.sort(compare));
输出结果为 [Object { name="wlz", age=25}, Object { name="zlw", age=24}] ,可以看到数组已经按照 name 属性进行了排序。我们可以对上面的比较函数再改造一下:
var compare = function (prop) { return function (obj1, obj2) { var val1 = obj1[prop]; var val2 = obj2[prop];if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } }
如果想按照 age 进行排序, arr.sort(compare("age")) 即可。
但是对age属性进行排序时需要注意了,如果age属性的值是数字,那么排序结果会是我们想要的。但很多时候我们从服务器传回来的数据中,属性值通常是字符串。现在我把上面的数组改为:
var arr = [{name: "zlw", age: "24"}, {name: "wlz", age: "5"}];
可以看到,我把 age 属性由数字改为了字符串,第二个数组项的 age 值改为了 "5" 。再次调用 arr.sort(compare("age")) 后,结果为:
[Object { name="zlw", age="24"}, Object { name="wlz", age="5"}]
我们的期望是5排在25前面,但是结果不是。这是因为当两个数字字符串比较大小时,会比较它们的ASCII值大小,比较规则是:从第一个字符开始,顺次向后直到出现不同的字符为止,然后以第一个不同的字符的ASCII值确定大小。所以"24"与"5"比较大小时,先比较”2“与"5"的ASCII值,显然”2“的ASCII值比"5"小,即确定排序顺序。
现在,我们需要对比较函数再做一些修改:
var compare = function (prop) { return function (obj1, obj2) { var val1 = obj1[prop]; var val2 = obj2[prop]; if (!isNaN(Number(val1)) && !isNaN(Number(val2))) { val1 = Number(val1); val2 = Number(val2); } if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } }
在比较函数中,先把比较属性值转化为数字 Number(val1) 再通过 !isNaN(Number(val1)) 判断转化后的值是不是数字(有可能是NaN),转化后的值如果是数字,则比较转换后的值,这样就可以得到我们想要的结果了, 调用 arr.sort(compare("age")) 得到:
[Object { name="wlz", age="5"}, Object { name="zlw", age="24"}]
可以看到,确实是按正确的方式排序了。
这篇文章所讲的都是基础的,没什么技术含量,只是最近项目中遇到了对数组对象进行排序的问题,所以在这里写出来分享一下,相信总能帮到一些朋友。
好文要顶 关注我 收藏该文
那时候的我
关注 - 17
粉丝 - 84
+加关注
16
0
« 上一篇:CSS3图片轮播效果
» 下一篇:js中call、apply、bind的用法
ADD YOUR COMMENT
#1楼 接二连珊 2017-10-25 17:44
不错,学习了
支持(1)反对(0)
#2楼 德鲁叔叔 2018-07-01 20:52
引用在比较函数中,先把比较属性值转化为数字 Number(val1) 再通过 !isNaN(Number(val1)) 判断转化后的值是不是数字(有可能是NaN)
支持(0)反对(0)
刷新评论刷新页面返回顶部
注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。
【推荐】超50万VC++源码: 大型组态工控、电力仿真CAD与GIS源码库!
【前端】SpreadJS表格控件,可嵌入应用开发的在线Excel
【免费】程序员21天搞定英文文档阅读
【推荐】如何快速搭建人工智能应用?
最新IT新闻:
· 偷听的智能音箱都忍不下去了:别BB,我给你们报警吧
· 第一次月球背面软着陆:嫦娥四号着陆器、月球车外观公布
· 科大讯飞、森马服饰否认投资红芯浏览器
· ETH断崖暴跌,融资缩水,创业者割肉度日
· 西湖大学重金求才!全球一流待遇挖角哈佛耶鲁,阿里高P辞职读AI
» 更多新闻...
最新知识库文章:
· 被踢出去的用户
· 成为一个有目标的学习者
· 历史转折中的“杭派工程师”
· 如何提高代码质量?
· 在腾讯的八年,我的职业思考
» 更多知识库文章...
个人独立博客:
http://zlwis.me
Github:https://github.com/lwzhang
昵称:那时候的我
园龄:4年4个月
粉丝:84
关注:17
+加关注
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
29 | 30 | 31 | 1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
26 | 27 | 28 | 29 | 30 | 31 | 1 | |||
2 | 3 | 4 | 5 | 6 | 7 | 8 |