作者: James Hibbard
译者:前端小智
来源:sitepoint

点赞再看,养成习惯

本文 GitHub https://github.com/qq449245884/xiaozhi 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。

最近开源了一个 Vue 组件,还不够完善,欢迎大家来一起完善它,也希望大家能给个 star 支持一下,谢谢各位了。

github 地址:https://github.com/qq449245884/vue-okr-tree

如果需要按特定顺序对对象数组进行排序,我们很有可能会直接找个 JS 库来用。其实大可不必,JS 原生中的 Array.sort就能直接一些复杂又漂亮的排序。

本文中,将介绍一些 Array.sort 的常规排序和一些骚操作。

基本数组排序

默认情况下,Array.sort函数将数组中需要排序的每个元素转换为字符串,并按 Unicode 顺序对其进行比较。

const foo = [9, 1, 4, 'zebroid', 'afterdeck'];
foo.sort(); // returns [ 1, 4, 9, 'afterdeck', 'zebroid' ]const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }];
bar.sort(); // returns [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]

你可能会好奇为啥32排在5之前。 发生这种情况是因为数组中的每个元素都首先转换为字符串,并且按照Unicode顺序,"32""5"之前。

需要注意的是,Array.sort会更改原数组。

const baz = ['My cat ate my homework', 37, 9, 5, 17];
baz.sort(); // baz数组被修改
console.log(baz); // shows [ 17, 37, 5, 9, 'My cat ate my homework' ]

为避免这种情况,我们可以创建要排序的数组的新实例,然后在新的数组上进行修改。 这里可以使用 Array.slice它返回是一个新的数组实例。

// 创建baz数组的新实例并对其进行排序
const sortedBaz = baz.slice().sort();

我们还可以使用 ES6 中的展开运算符来做:

const sortedBaz = [...baz].sort();

在两种情况下,输出是相同的:

console.log(baz); // ['My cat ate my homework', 37, 9, 5, 17];
console.log(sortedBaz); // [ 17, 37, 5, 9, 'My cat ate my homework' ]

单独使用Array.sort不能对对象数组进行排序。但不必担心,sort 的还提供一个参数,该参数使数组元素根据compare函数的返回值进行排序。

使用比较函数进行排序

假设foobarcompare函数要比较的两个元素,compare函数的返回值设置如下:

  1. 小于0foobar之前
  2. 大于0barfoo之前
  3. 等于0foobar彼此保持不变。

来看一个简单的示例:

const nums = [79, 48, 12, 4];function compare(a, b) {if (a > b) return 1;if (b > a) return -1;return 0;
}nums.sort(compare);
// => 4, 12, 48, 79

我们可以稍微重构一下:

function compare(a, b) {return a - b;
}

使用在使用箭头函数进行重构:

nums.sort((a, b) => a - b);

如何对对象数组进行排序

现在,我们来按一下对对象数组的排序。假设有下面的 singers 数组:

const singers = [{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];

我们可以使用 compare函数,然后根据 singers 中的 band 字段来进行排序。

function compare(a, b) {// 使用 toUpperCase() 忽略字符大小写const bandA = a.band.toUpperCase();const bandB = b.band.toUpperCase();let comparison = 0;if (bandA > bandB) {comparison = 1;} else if (bandA < bandB) {comparison = -1;}return comparison;
}singers.sort(compare);/* returns [{ name: 'Steven Tyler', band: 'Aerosmith',  born: 1948 },{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }
] */

如果要让上面的顺序相反,可以这么做:

function compare(a, b) {...// 乘以-1来反转返回值return comparison * -1;
}

创建一个动态排序函数

最后,排序函数更具动态性。

我们创建一个排序函数,可以使用该函数对一组对象进行排序,这些对象的值可以是字符串或数字。 该函数有两个参数-我们要排序的键和返回结果的顺序(即升序或降序):

const singers = [{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];function compareValues(key, order = 'asc') {return function innerSort(a, b) {if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {// 该属性在任何一个对象上都不存在return 0;}const varA = (typeof a[key] === 'string')? a[key].toUpperCase() : a[key];const varB = (typeof b[key] === 'string')? b[key].toUpperCase() : b[key];let comparison = 0;if (varA > varB) {comparison = 1;} else if (varA < varB) {comparison = -1;}return ((order === 'desc') ? (comparison * -1) : comparison);};
}

使用:

//数组按`band`排序,默认为升序
singers.sort(compareValues('band'));// 数组按 `band` 降序排序
singers.sort(compareValues('band', 'desc'));// 数组按 `name` 升序排序
singers.sort(compareValues('name'));// 数 组born 降序排序
singers.sort(compareValues('born', 'desc'));

在上面的代码中,hasOwnProperty方法用于检查指定的属性是否在每个对象上定义,且没有通过原型链继承。如果没有在两个对象上定义,函数返回0,排序顺序保持不变(即对象之间保持不变)。

typeof运算符还用于检查属性值的数据类型,这使函数可以确定对数组进行排序的正确方法。 如果指定属性的值是一个字符串,则使用toUpperCase方法将其所有字符都转换为大写,因此排序时将忽略字符大小写

最后,你可以根据自己需求来调整上面的函数。

String.prototype.localeCompare()

在上面的示例中,我们希望能够对对象数组进行排序,其值可以是字符串或数字。 但是,如果我们知道处理值是字符串的对象,则可以使用 JS 的localeCompare方法

比较两个字符串,并返回下列值中的一个:

  • 如果 字符串 在 字母 表中 应该 排在 字符串 参数 之前, 则 返回 一个 负数;
  • 如果 字符串 等于 字符串 参数, 则 返回 0;
  • 字符串 在 字母 表中 应该 排在 字符串 参数 之后, 则 返回 一个 正数;
['bjork', 'Bjork', 'Björk'].sort();
// [ 'Bjork', 'Björk', 'bjork' ]['bjork', 'Bjork', 'Björk'].sort((a, b) => a.localeCompare(b));
//  [ 'bjork', 'Bjork', 'Björk' ]

根据compareValues函数,我们可以这么写:

function compareValues(key, order = 'asc') {return function innerSort(a, b) {if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) return 0;const comparison = a[key].localeCompare(b[key]);return ((order === 'desc') ? (comparison * -1) : comparison);};
}

总结

上面就是使用普通JS 函数对对象数组排序的简短的介绍。尽管许多库都提供了这种动态排序能力,但我们自己实现这个方法其实也不信。另外,了解幕后发生了对我们来说并没有坏处。

今天就跟大家分享到这里了,感谢大家的观看,我们下期再见。


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

原文:https://www.sitepoint.com/sort-an-array-of-objects-in-javascript/

交流

文章每周持续更新,可以微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,另外关注公众号,后台回复福利,即可看到福利,你懂的。

如何在JavaScript中对对象数组进行排序相关推荐

  1. java对象数组排序_如何在Java中对对象数组进行排序?

    小编典典 你有两种方法可以使用Arrays实用程序类 实现一个Comparator并将数组与比较器一起传递给sort方法,该方法将其作为第二个参数. 在对象所属的类中实现Comparable接口,并将 ...

  2. 如何在Javascript中访问对象的第一个属性?

    本文翻译自:How to access the first property of an object in Javascript? Is there an elegant way to access ...

  3. 如何在JavaScript中获取字符串数组的字符串?

    本文翻译自:How do you get a string to a character array in JavaScript? How do you get a string to a chara ...

  4. 如何从JavaScript中的对象数组中获得不同的值?

    本文翻译自:How to get distinct values from an array of objects in JavaScript? Assuming I have the followi ...

  5. js数组查找最接近_如何从javascript中的对象数组中获取最接近的先前id

    我对您的代码进行了一些更改,现在应该可以正常工作了.看一看. const array = [{id:3}, {id:4}, {id:10}, {id:15}]; // you should order ...

  6. 如何在JavaScript中比较数组?

    本文翻译自:How to compare arrays in JavaScript? I'd like to compare two arrays... ideally, efficiently. 我 ...

  7. 如何检查数组是否包含JavaScript中的对象?

    In this article, we will look at various methods to check if an array includes an object in JavaScri ...

  8. javascript中对一个对象数组按照对象某个属性进行排序

    在javascript中,对象和数组是两种不同的类型,这和php中的数组概念不同.在javascript中,也有一些精妙的算法,用来对一些对象进行排序.我在面试迅雷的时候,也拿到一道题,当时做题的时候 ...

  9. 如何在JavaScript中实现链接列表

    If you are learning data structures, a linked list is one data structure you should know. If you do ...

最新文章

  1. c++引用的自我见解
  2. 多天线技术是LTE的重要演进方向已成为产业共识
  3. 图像傅里叶变换-不错
  4. 限制IIS站点的内存,避免级联影响
  5. 有史以来最详细 安装部署Kubernetes Dashboard (补充解决官方出现的一些RBAC CERT等问题)
  6. Wireshark中遇到的epoch time
  7. python机器学习-sklearn挖掘乳腺癌细胞(五)
  8. STM32:GPIO四种输入输出模式。
  9. java class多重泛型_多重继承求泛型类的类型
  10. 超好用的文件转换神器!拿走不谢~
  11. 【路径规划】基于狼群算法之三维路径规划matlab源码
  12. (翻译)反馈循环模式(Feedback loops)
  13. Glide 加载webp动图实战(解决图片每帧间隔过长,动图单次播放,二次播放动图时首帧是动图最后一帧的问题)
  14. 操作系统实验:系统内存使用统计
  15. 逐浪CMS2 x3.8新功能:定时执行C#代码让二次开发虎虎添翼
  16. java开发微信公众号:微信公众号对接
  17. 企企通X长青热能SRM项目成功上线,共同打造智能高效的数字化采购管理平台
  18. python中如何打开文件选择框
  19. CSS+HTML实现学成在线静态页面
  20. 「技术综述」人脸脸型分类研究现状

热门文章

  1. TerraBuilder 操作制作MPT
  2. 从说话人识别demo开始学习kaldi--(6)训练UBM和PLDA
  3. 西安市2012年教师资格证考试报名时间:3月10-15日
  4. webmail 客户端_最受欢迎的Webmail客户端
  5. linux webmail发送邮件,C# 邮件发送方法【webMail方式】
  6. 35、sparkSQL及DataFrame
  7. 用Html+css写一个渐变背景的个人名片
  8. 802.11无线网络权威——(三、MAC基础)
  9. 大学生求职简历如何制作?
  10. vue文件如何引入icon图标并使用