资讯详情

资讯详情

现代 JavaScript 教程实战:用 `Array.prototype.sort` 与比较函数对对象数组按年龄排序

文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载本篇文章以《现代 JavaScript 教程》zh.javascript.info中“数组方法”章节的实战习题“按年龄对用户排序”8-sort-objects为骨架完整讲解如何为对象数组编写比较函数、理解sort的原位排序语义并结合仓库内 数组方法总览章节 的sort(fn)原理与同章其他排序习题做纵深拓展。读完本文你将掌握给sort传比较函数的正确姿势、数字与字符串排序的差异、对象数组排序的完整套路以及在不破坏原数组时如何安全排序。习题背景对对象数组按age排序在仓库的1-js/05-data-types/05-array-methods/8-sort-objects/目录下习题 task.md 提出了这样一个需求编写函数sortByAge(users)取得对象数组的age属性并根据age对这些对象数组进行排序。题目给出的示例数据如下let john { name: John, age: 25 }; let pete { name: Pete, age: 30 }; let mary { name: Mary, age: 28 }; let arr [ pete, john, mary ]; sortByAge(arr); // now: [john, mary, pete] alert(arr[0].name); // John alert(arr[1].name); // Mary alert(arr[2].name); // Pete注意两个关键点数组元素不是数字而是对象——每个元素是{ name, age }结构排序依据是对象的age数值属性期望结果按年龄升序John25→ Mary28→ Pete30函数直接修改原数组arr排序完成后arr[0]、arr[1]、arr[2]的顺序即验证结果。这意味着我们面对的是一个典型的“对象数组按某个属性排序”场景——这是日常业务代码用户列表、订单列表、排行榜中最常见的排序需求之一。官方解答一行比较函数搞定习题的标准解答位于 solution.md核心只有一行function sortByAge(arr) { arr.sort((a, b) a.age - b.age); } let john { name: John, age: 25 }; let pete { name: Pete, age: 30 }; let mary { name: Mary, age: 28 }; let arr [ pete, john, mary ]; sortByAge(arr); // 排序后的数组为[john, mary, pete] alert(arr[0].name); // John alert(arr[1].name); // Mary alert(arr[2].name); // Pete这段代码之所以正确依赖两个层面的机制1. 比较函数返回值可以是任意正负数在 数组方法章节的sort(fn)小节 中教程特别强调了一个“聪明提示”比较函数实际上只需要返回一个正数表示“大于”一个负数表示“小于”并不要求严格返回 1 / 0 / -1。因此a.age - b.age这种写法是合法的当a.age b.age时a.age - b.age为负数 →a排在b前面升序当a.age b.age时结果为正数 →b排在a前面当两者相等时结果为0顺序保持不变。2. 比较函数负责“抽取”可比较的数值sort本身不知道对象之间如何比较大小——它只知道“你给了我一个比较函数我就按它来排列元素”。比较函数(a, b) a.age - b.age的作用正是把“如何比较两个对象”翻译成“如何比较两个数字”让底层的通用排序算法得以执行。为什么不能直接调用arr.sort()默认按字符串排序如果你直接对对象数组调用无参的arr.sort()得到的结果几乎一定是错误的。原因在 article.md 的sort(fn)小节中有明确说明这些元素默认情况下被按字符串进行排序。sort的默认行为会把每个元素先转换为字符串再按词典顺序比较。对[1, 2, 15]排序得到的是1, 15, 2因为字符串15排在2之前对对象数组排序时每个对象会被转成[object Object]所有元素“相等”顺序不变排序毫无意义。所以只要涉及数字排序或对象排序必须显式传入比较函数。这正是本习题的核心教学点。对比函数的一般形态与箭头函数写法教程 article.md 给出了比较函数的完整形态function compare(a, b) { if (a b) return 1; // 如果第一个值比第二个值大 if (a b) return 0; // 如果两个值相等 if (a b) return -1; // 如果第一个值比第二个值小 }而更简洁的写法是直接返回差值。教程同小节还给出了箭头函数的推荐写法arr.sort( (a, b) a - b );本习题的解答(a, b) a.age - b.age就是这一写法的对象版把比较逻辑从“比较数字本身”泛化为“比较对象的某个数值属性”。同一章节的姊妹习题佐证这套“差值返回”的写法在同一章节的其他习题中反复出现印证了它是排序对象/数字数组的通用套路降序排列4-sort-back/solution.mdlet arr [5, 2, 1, -10, 8]; arr.sort((a, b) b - a); // 交换 a、b 位置即得降序 alert( arr );只需把a - b换成b - a升序就变成降序——对应到本习题若要按年龄降序写成(a, b) b.age - a.age即可。随机洗牌9-shuffle/solution.md虽然该习题展示了用array.sort(() Math.random() - 0.5)洗牌的做法但教程同时指出sort是“黑匣子”用随机比较函数做洗牌会导致各排列概率不均示例中123与213出现约 25 万次其余约 12.5 万次应改用 Fisher-Yates 算法。这从反面提醒我们比较函数应当返回确定、自洽的序关系而a.age - b.age正是一个稳定、一致的比较器。原位排序语义与不破坏原数组的排序教程明确强调sort是原位in-place排序article.md 写道“该方法重新排列arr的内容”并且“它还返回排序后的数组但是返回值通常会被忽略因为修改了arr本身”章节末尾的方法清单 也注明“sortreverse和splice方法修改的是数组本身”。因此本习题中sortByAge(arr)直接修改传入的arr调用后无需接收返回值验证方式就是读取arr[0]、arr[1]、arr[2]如果业务上需要保留原数组必须先复制再排序。同一章节的习题 5-copy-sort-array/task.md 就专门考察了这一点——利用arr.slice()或[...arr]得到副本后对副本排序原数组保持不变let arr [HTML, JavaScript, CSS]; let sorted copySorted(arr); alert( sorted ); // CSS, HTML, JavaScript alert( arr ); // HTML, JavaScript, CSS (no changes)进阶注意事项字符串属性的排序陷阱如果对象数组要按字符串属性如姓名name排序直接a.name - b.name会产生NaN排序失效。此时应使用关系运算符配合三元表达式或使用localeCompare。教程 article.md 的示例说明对[Österreich, Andorra, Vietnam]用(a, b) a b ? 1 : -1会得到错误顺序Andorra, Vietnam, Österreich而(a, b) a.localeCompare(b)才能按语言规则正确排序Andorra, Österreich, Vietnam。这提示我们比较函数必须与属性类型匹配——数值属性用差值字符串属性用localeCompare。相等年龄时保持原顺序a.age - b.age在年龄相等时返回0排序算法会认为两者等价。根据 ECMAScript 规范现代引擎如 V8 的 Timsort的sort是稳定排序相等元素保持相对顺序。因此按年龄排序时年龄相同的人会保留它们在原数组中的先后顺序无需额外处理。小结本习题的完整结论可归纳为场景比较函数写法数字数组升序(a, b) a - b数字数组降序(a, b) b - a对象数组按数值属性升序本题(a, b) a.age - b.age对象数组按字符串属性(a, b) a.name.localeCompare(b.name)一句话总结对对象数组排序核心就是写一个“能抽出可比数值/字符串并返回正负号或 0”的比较函数然后把它交给arr.sort(fn)。本篇解答与完整原理可继续在仓库中查阅习题任务、官方解答、数组方法总览。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐zh.javascript.info 教程实战用 Array.sort 按年龄对对象数组排序sortByAge 精讲zh.javascript.info 教程实战用 Array.sort 按年龄对对象数组排序sortByAge 精讲 本篇技术指南以《现代 JavaScr文档教程前端JavaScript 教程实战用 Array.prototype.sort 实现按 age 属性排序用户对象JavaScript 教程实战用 Array.prototype.sort 实现按 age 属性排序用户对象 导读 本文基于 Modern JavaScrip文档/教程前端Modern JavaScript 教程数组降序排序——从 sort((a, b) b - a) 吃透 Array.prototype.sort 比较函数Modern JavaScript 教程数组降序排序——从 sort a, b b a 吃透 Array.prototype.sort 比较函数 本篇文章文档/教程前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →