js中的数组对象排序分析


Posted in Javascript onDecember 11, 2018

一、普通数组排序

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

可以看到,确实是按正确的方式排序了。

这篇文章所讲的都是基础的,没什么技术含量,只是最近项目中遇到了对数组对象进行排序的问题,所以在这里写出来分享一下,相信总能帮到一些朋友。

Javascript 相关文章推荐
论坛特效代码收集(落伍转发-不错)
Dec 02 Javascript
js函数参数设置默认值的一种变通实现方法
May 26 Javascript
javascript格式化指定日期对象的方法
Apr 21 Javascript
JS中常用的输出方式(五种)
Jun 12 Javascript
jQuery插件扩展测试实例
Jun 21 Javascript
详解Node.js:events事件模块
Nov 24 Javascript
React Native中NavigatorIOS组件的简单使用详解
Jan 27 Javascript
node.js监听文件变化的实现方法
Apr 17 Javascript
vue路由拦截器和请求拦截器知识点总结
Nov 08 Javascript
JS实现扫码枪扫描二维码功能
Jan 03 Javascript
Openlayers+EasyUI Tree动态实现图层控制
Sep 28 Javascript
vue/cli 配置动态代理无需重启服务的方法
May 20 Vue.js
详解Vue源码之数据的代理访问
Dec 11 #Javascript
浅谈Vue 性能优化之深挖数组
Dec 11 #Javascript
vue 内置过滤器的使用总结(附加自定义过滤器)
Dec 11 #Javascript
Vue入门之数量加减运算操作示例
Dec 11 #Javascript
简单的React SSR服务器渲染实现
Dec 11 #Javascript
Vuex 单状态库与多模块状态库详解
Dec 11 #Javascript
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
Dec 11 #Javascript
You might like
DOTA2 玩家自创拉野攻略 特色英雄快速成长篇
2020/04/20 DOTA
印尼林东PWN黄金曼特宁咖啡豆:怎么冲世界上最醇厚的咖啡冲煮教程
2021/03/03 冲泡冲煮
PHP获取用户的浏览器与操作系统信息的代码
2012/09/04 PHP
基于Discuz security.inc.php代码的深入分析
2013/06/03 PHP
标准版Eclipse搭建PHP环境的详细步骤
2015/11/18 PHP
PHP读取大文件末尾N行的高效方法推荐
2016/06/03 PHP
关于PHP转换超过2038年日期出错的问题解决
2017/06/28 PHP
require.js深入了解 require.js特性介绍
2014/09/04 Javascript
jquery实现类似淘宝星星评分功能实例
2014/09/12 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
ExtJs动态生成treepanel的Json格式
2015/07/19 Javascript
jQuery1.9.1源码分析系列(十六)ajax之ajax框架
2015/12/04 Javascript
JS闭包与延迟求值用法示例
2016/12/22 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
JavaScript中的函数式编程详解
2020/08/22 Javascript
[01:54]TI珍贵瞬间系列(三):翻盘
2020/08/28 DOTA
python中的实例方法、静态方法、类方法、类变量和实例变量浅析
2014/04/26 Python
python关键字and和or用法实例
2015/05/28 Python
python发送HTTP请求的方法小结
2015/07/08 Python
Python编程之黑板上排列组合,你舍得解开吗
2017/10/30 Python
基于Python log 的正确打开方式
2018/04/28 Python
Win10下python 2.7.13 安装配置方法图文教程
2018/09/18 Python
Python pyinotify模块实现对文档的实时监控功能方法
2018/10/13 Python
Python解决两个整数相除只得到整数部分的实例
2018/11/10 Python
python3利用ctypes传入一个字符串类型的列表方法
2019/02/12 Python
浅谈python3.6的tkinter运行问题
2019/02/22 Python
Python使用pandas和xlsxwriter读写xlsx文件的方法示例
2019/04/09 Python
详解Pycharm第三方库的安装及使用方法
2020/12/29 Python
使用placeholder属性设置input文本框的提示信息
2020/02/19 HTML / CSS
ProBikeKit英国:在线公路自行车之家
2017/02/10 全球购物
英国户外服装品牌:Craghoppers
2019/04/25 全球购物
大学自我鉴定范文
2013/12/26 职场文书
毕业生求职信
2014/06/10 职场文书
企业爱岗敬业演讲稿
2014/09/04 职场文书
2014业务员年终工作总结
2014/12/09 职场文书
python​格式化字符串
2022/04/20 Python