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 相关文章推荐
理解JAVASCRIPT中hasOwnProperty()的作用
Jun 05 Javascript
javascript文件中引用依赖的js文件的方法
Mar 17 Javascript
JavaScript通过元素的ID和name设置样式
Jul 08 Javascript
JavaScript访问字符串中单个字符的两种方法
Jul 03 Javascript
用JavaScript判断CSS浏览器类型前缀的两种方法
Oct 08 Javascript
JavaScript中三种异步上传文件方式
Mar 06 Javascript
vue-cli创建的项目,配置多页面的实现方法
Mar 15 Javascript
微信小程序block的使用教程
Apr 01 Javascript
JS实现获取进今年第几天是周几的方法分析
Jun 27 Javascript
对angular2中的ngfor和ngif指令嵌套实例讲解
Sep 12 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
Jun 17 Javascript
Vue路由 重定向和别名的区别说明
Sep 09 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
无法载入 mcrypt 扩展,请检查 PHP 配置终极解决方案
2011/07/18 PHP
解析php中反射的应用
2013/06/18 PHP
解决FastCGI 进程超过了配置的活动超时时限的问题
2013/07/03 PHP
PHP+jquery+ajax实现即时聊天功能实例
2014/12/23 PHP
必须收藏的23个php实用代码片段
2016/02/02 PHP
PHP之认识(二)关于Traits的用法详解
2019/04/11 PHP
一个判断email合法性的函数[非正则]
2008/12/09 Javascript
Javascript 中介者模式实例
2009/12/16 Javascript
extJs 常用到的增,删,改,查操作代码
2009/12/28 Javascript
jquery 插件开发 extjs中的extend用法小结
2013/01/04 Javascript
使用GruntJS构建Web程序之安装篇
2014/06/04 Javascript
详解JavaScript语言的基本语法要求
2015/11/20 Javascript
基于canvas实现的绚丽圆圈效果完整实例
2016/01/26 Javascript
Angular.js如何从PHP读取后台数据
2016/03/24 Javascript
基于jQuery的左滑出现删除按钮的示例
2017/08/29 jQuery
nodejs aes 加解密实例
2018/10/10 NodeJs
基于Fixed定位的框选功能的实现代码
2019/05/13 Javascript
Echarts动态加载多条折线图的实现代码
2019/05/24 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
如何利用JS将手机号中间四位变成*号
2020/09/29 Javascript
[01:49]一目了然!DOTA2DotA快捷操作对比第二弹
2014/05/16 DOTA
Python中的浮点数原理与运算分析
2017/10/12 Python
Python编程之基于概率论的分类方法:朴素贝叶斯
2017/11/11 Python
Python实现统计给定字符串中重复模式最高子串功能示例
2018/05/16 Python
浅析python连接数据库的重要事项
2021/02/22 Python
matplotlib bar()实现百分比堆积柱状图
2021/02/24 Python
HTML实现代码雨源码及效果示例
2020/02/25 HTML / CSS
马来西亚在线购物:POPLOOK.com
2019/12/09 全球购物
软件缺陷的分类都有哪些
2014/08/22 面试题
计算机专业应届生求职信
2014/04/06 职场文书
给老婆的检讨书1000字
2015/01/01 职场文书
建党伟业观后感
2015/06/01 职场文书
惊涛骇浪观后感
2015/06/05 职场文书
2015年中学团委工作总结
2015/07/22 职场文书
javascript函数式编程基础
2021/09/15 Javascript
MySQL数据库配置信息查看与修改方法详解
2022/06/25 MySQL