做者: James Hibbard
译者:前端小智
来源:sitepoint
点赞再看,养成习惯本文
GitHub
https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。javascript
最近开源了一个 Vue 组件,还不够完善,欢迎你们来一块儿完善它,也但愿你们能给个 star 支持一下,谢谢各位了。前端
github 地址:https://github.com/qq449245884/vue-okr-treevue
若是须要按特定顺序对对象数组进行排序,咱们颇有可能会直接找个 JS 库来用。其实大可没必要,JS 原生中的 Array.sort
就能直接一些复杂又漂亮的排序。java
本文中,将介绍一些 Array.sort 的常规排序和一些骚操做。git
默认状况下,Array.sort
函数将数组中须要排序的每一个元素转换为字符串,并按 Unicode
顺序对其进行比较。github
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
函数的返回值进行排序。
假设foo
和bar
是compare
函数要比较的两个元素,compare
函数的返回值设置以下:
0
:foo
在bar
以前0
:bar
在foo
以前0
:foo
和bar
彼此保持不变。来看一个简单的示例:
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
方法将其全部字符都转换为大写,所以排序时将忽略字符大小写
最后,你能够根据本身需求来调整上面的函数。
在上面的示例中,咱们但愿可以对对象数组进行排序,其值能够是字符串或数字。 可是,若是咱们知道处理值是字符串的对象,则可使用 JS 的localeCompare
方法
比较两个字符串,并返回下列值中的一个:
['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/sor...
文章每周持续更新,能够微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了不少个人文档,欢迎Star和完善,你们面试能够参照考点复习,另外关注公众号,后台回复福利,便可看到福利,你懂的。