首页 / 资讯中心 / 文章详情

使用 Set 实现数组去重:en.javascript.info「Filter unique array members」任务解析

使用 Set 实现数组去重:en.javascript.info「Filter unique array members」任务解析 ★ FEATURED ARTICLE
文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载本指南以现代 JavaScript 教程en.javascript.info中1-js/05-data-types章节的 数组去重任务 为主线系统讲解如何利用Set集合实现任意类型数组的unique(arr)去重函数。读完本文你将掌握Set的去重语义、Array.from与展开运算符的互转写法、复杂度对比以及仓库测试用例的验证方法并能将同一思路迁移到基于Map的分组去重场景。任务背景与要求该任务位于 Map and Set 章节 的练习部分属于数组去重unique array members专项训练。题目原文要求如下给定数组arr编写函数unique(arr)返回一个由arr中唯一项组成的数组。示例输入输出function unique(arr) { /* your code */ } let values [Hare, Krishna, Hare, Krishna, Krishna, Krishna, Hare, Hare, :-O ]; alert( unique(values) ); // Hare, Krishna, :-O题目附带两条关键提示P.S. 数据类型不限于字符串示例用的是字符串但数组中可以存放任意类型的值P.P.S. 要求使用Set这是本节练习的核心意图——用刚学过的Set集合来存储唯一值而不是用filterindexOf这类 O(n²) 的手工方案。解题思路为什么Set是天然的去重工具在 Map and Set 章节 中Set被定义为无键值的特殊集合每个值在集合中最多出现一次ASetis a special type collection - set of values (without keys), where each value may occur only once.其核心方法包括方法/属性作用new Set([iterable])创建集合传入可迭代对象通常是数组时把其中的值复制进集合set.add(value)添加值若值已存在则什么也不做并返回集合本身set.has(value)返回true/false判断值是否存在set.delete(value)移除值值存在时返回trueset.clear()清空集合set.size元素个数重复调用set.add(value)不产生任何效果这一特性正是去重任务的全部答案把整个数组逐一add进Set重复项会被自动过滤剩下的就是唯一值集合。官方参考解法Array.from(new Set(arr))仓库中该任务的官方参考实现位于 _js.view/solution.js只有一行核心代码function unique(arr) { return Array.from(new Set(arr)); }其执行分两步new Set(arr)利用构造函数接受可迭代对象的特性把数组元素一次性复制进集合重复项被自动丢弃Array.from(new Set(arr))把Set可迭代对象转回数组返回。一个更简洁的等价写法是展开运算符function unique(arr) { return [...new Set(arr)]; }两种方式语义完全一致Array.from更贴近教程正文的讲授风格展开运算符则常见于现代代码库。无论哪种写法都具备两个重要性质保持首次出现顺序Set的迭代按插入顺序进行教程总结中明确指出Map和Set的迭代始终遵循插入顺序因此结果数组中每个唯一元素的位置等于它在原数组中的首次出现位置不修改原数组Set只是复制引用/值不会原地改写输入数组。仓库测试用例行为验证该任务附带完整的 Mocha 测试套件 _js.view/test.js用两个用例锁定了函数必须满足的行为describe(unique, function() { it(removes non-unique elements, function() { let strings [Hare, Krishna, Hare, Krishna, Krishna, Krishna, Hare, Hare, :-O ]; assert.deepEqual(unique(strings), [Hare, Krishna, :-O]); }); it(does not change the source array, function() { let strings [Krishna, Krishna, Hare, Hare]; unique(strings); assert.deepEqual(strings, [Krishna, Krishna, Hare, Hare]); }); });两个断言的解读assert.deepEqual(unique(strings), [Hare, Krishna, :-O])不仅要求结果去重还要求保持插入顺序——Hare在原数组中首次出现于索引 0Krishna首次出现于索引 1:-O最后输出顺序与首次出现顺序严格一致does not change the source array调用unique后原数组不变说明解法是纯函数式的没有副作用。这正是new Set(arr)Array.from组合优于arr.splice类原地改写的关键。去重原理纵深SameValueZero 与元素类型Set判断值是否重复时采用与Map相同的SameValueZero算法ECMAScript 规范定义不可自定义。它与严格相等几乎一致唯一差异是NaN被视为等于自身。这意味着直接套用本解法时NaN能被正确去重unique([NaN, NaN, 1]); // [NaN, 1]若用 indexOf 方案则会得到 [NaN, NaN, 1]对象按引用去重两个内容相同但引用不同的对象属于不同元素不会被合并let a { id: 1 }, b { id: 1 }; unique([a, b, a]); // [{ id: 1 }, { id: 1 }]两个不同引用 一个重复引用基础类型值按值去重Hare与Hare、数字1与字符串1是不同元素语义不会被混淆。这也呼应了任务中可以使用任意类型的值的提示解法对字符串、数字、NaN、布尔值、undefined、对象引用等所有类型一视同仁地按上述规则去重无需任何类型分支。复杂度对比Set 方案 vs 手工方案教程正文在介绍Set时给出了对比若不使用Set替代方案是用数组配合arr.find在每次插入时检查重复但性能会差得多因为该方法需要遍历整个数组逐一比对元素。对长度为 n 的数组方案时间复杂度说明new Set(arr)Array.fromO(n)平均Set内部针对唯一性检查做了高度优化插入与查询均为常数级平均filterindexOf/ 循环 findO(n²)每个元素都要线性扫描已收集的部分先排序再去重O(n log n)需额外排序步骤且会破坏原始相对顺序因此对真实数据集Set方案在时间复杂度和代码简洁度上都是压倒性选择这正是本任务强制要求使用Set的原因。延伸练习从 Set 去重到 Map 分组去重同章节的下一个任务 Filter anagrams过滤变位词 是同一思路的进阶若需要按某个规范化键去重、并保留该组中的代表值Set不够用而Map正好胜任。其参考实现 _js.view/solution.js 展示了排序字符串作为键的技巧function aclean(arr) { let map new Map(); for(let word of arr) { let sorted word.toLowerCase().split().sort().join(); map.set(sorted, word); } return Array.from(map.values()); }该实现的配套测试 _js.view/test.js 验证了两点每个变位词组只保留 1 个单词、且大小写不敏感era与EAR视为一组。这与unique任务形成了完美的对照学习链Set去重值本身作为唯一性依据适合整值去重Map分组去重键规范化结果作为唯一性依据值组内代表另行选择适合按映射键去重。常见陷阱与实战建议不要用map[key]风格访问教程正文特别提醒Map必须使用方法set/get/has而非下标赋值后者会退化为普通对象语义。Set同理务必使用add/has对象去重先想清楚语义Set按引用去重若想按对象的某个字段去重需要Map 字段键如变位词任务那样保持顺序是特性不是巧合Set迭代按插入顺序进行Array.from(new Set(arr))的结果天然保留首次出现顺序这是它优于排序去重方案的另一个原因数值与字符串不混同1与1是不同的集合元素涉及接口数据时需要留意隐式类型转换。小结本任务用一行Array.from(new Set(arr))完美诠释了Set的核心价值O(n) 去重、保持首次出现顺序、不改动原数组、支持任意类型含NaN与对象引用。配套的 任务描述、参考解法 与 测试用例 组成了一套可运行、可验证的最小学习闭环掌握它之后再进入 变位词过滤任务 即可自然进阶到Map分组去重模式。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐JavaScript 数组去重实战从 unique() 任务看 includes 循环与 Set 优化JavaScript 数组去重实战从 unique 任务看 includes 循环与 Set 优化 导读 本文基于 Modern JavaScript Tut文档/教程前端en.javascript.info 实战任务解析用 Array.map 把对象数组映射为 id fullName 结构en.javascript.info 实战任务解析用 Array.map 把对象数组映射为 id fullName 结构 本篇基于 Modern Java文档/教程前端Apktool 如何把 APK 拆成可编辑文件Apktool 如何把 APK 拆成可编辑文件 Apktool 是一个安卓 APK 逆向工具一行命令把安装包拆成资源文件和 Smali 代码改完再打包回 A逆向工程开发工具移动开发上一篇OrcaSlicer 命令行自动化切片指南10 分钟搞定单文件到批量生产下一篇喜马拉雅音频下载器3步解锁VIP内容实现音频永久保存创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站