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 相关文章推荐
jQueryUI的Dialog的简单封装
Jun 07 Javascript
jQuery的实现原理的模拟代码 -5 Ajax
Aug 07 Javascript
js禁止小键盘输入数字功能代码
Aug 01 Javascript
innerHTML与jquery里的html()区别介绍
Oct 12 Javascript
ExtJS4如何给同一个formpanel不同的url
May 02 Javascript
js淡入淡出焦点图幻灯片效果代码分享
Sep 08 Javascript
jQuery解决input元素的blur事件和其他非表单元素的click事件冲突问题
Aug 15 Javascript
jquery获取元素到屏幕四周可视距离的方法
Sep 05 jQuery
JQuery获取元素尺寸、位置及页面滚动事件应用示例
May 14 jQuery
Vue分页器实现原理详解
Jun 28 Javascript
对Layer UI 模块化的用法详解
Sep 26 Javascript
vue如何搭建多页面多系统应用
Jun 17 Javascript
详解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
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
2012/03/27 PHP
php实现遍历目录并删除指定文件中指定内容
2015/01/21 PHP
Linux系统中为php添加pcntl扩展
2016/08/28 PHP
php 截取GBK文档某个位置开始的n个字符方法
2017/03/08 PHP
js实现简单的购物车有图有代码
2014/05/26 Javascript
JavaScript中实现继承的三种方式和实例
2015/01/29 Javascript
jQuery制作仿Mac Lion OS滚动条效果
2015/02/10 Javascript
JQUERY实现网页右下角固定位置展开关闭特效的方法
2015/07/27 Javascript
BootStrap中按钮点击后被禁用按钮的最佳实现方法
2016/09/23 Javascript
微信小程序 网络API发起请求详解
2016/11/09 Javascript
JS键盘版计算器的制作方法
2016/12/03 Javascript
vue.js实现条件渲染的实例代码
2017/06/22 Javascript
浅析webpack 如何优雅的使用tree-shaking(摇树优化)
2017/08/16 Javascript
修改vue+webpack run build的路径方法
2018/09/01 Javascript
详解Vue中数组和对象更改后视图不刷新的问题
2018/09/21 Javascript
vue滚动tab跟随切换效果
2020/06/29 Javascript
JavaScript 几种循环方式以及模块化的总结
2020/09/03 Javascript
跟老齐学Python之字典,你还记得吗?
2014/09/20 Python
Python re模块介绍
2014/11/30 Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
2017/04/11 Python
Python实现邮件的批量发送的示例代码
2018/01/23 Python
python距离测量的方法
2018/03/06 Python
在Python中给Nan值更改为0的方法
2018/10/30 Python
python 读写文件包含多种编码格式的解决方式
2019/12/20 Python
利用Python如何实时检测自身内存占用
2020/05/09 Python
Keras构建神经网络踩坑(解决model.predict预测值全为0.0的问题)
2020/07/07 Python
Matlab中plot基本用法的具体使用
2020/07/17 Python
爬虫代理的cookie如何生成运行
2020/09/22 Python
CSS3 文字动画效果
2020/11/12 HTML / CSS
国际奢侈品品牌童装购物网站:Designer Childrenswear
2019/05/08 全球购物
如何利用find命令查找文件
2015/02/07 面试题
给水工程专业毕业生自荐信
2014/01/28 职场文书
群众路线教育实践活动方案
2014/10/31 职场文书
酒店人事专员岗位职责
2015/04/07 职场文书
原型和原型链 prototype和proto的区别详情
2021/11/02 Javascript
使用canvas仿Echarts实现金字塔图的实例代码
2021/11/11 HTML / CSS