尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Modern JavaScript 教程:用 Map 键值归组实现变位词(Anagram)过滤——`aclean` 解法深度剖析
文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载导读本文围绕 Modern JavaScript Tutorial本仓库 en.javascript.info中「Map 与 Set」一节的经典练习「过滤变位词」Filter anagrams 任务展开逐行剖析其官方解法 solution.md通过「按字母排序后的字符串」作为 Map 键将互为变位词的单词归入同一组并只保留一个代表词。读完本文你将掌握Map的键去重覆盖语义、split → sort → join字符串规范化的核心套路以及Map方案与普通对象方案的取舍并看到仓库内置测试 test.js 如何验证这两项行为。一、任务背景什么是变位词要过滤掉什么「变位词Anagram」指拥有相同数量的相同字母、但排列顺序不同的单词。任务文档 task.md 给出的示例是nap - pan ear - are - era cheaters - hectares - teachers要求编写函数aclean(arr)返回一个去掉变位词后的数组每个变位词组只保留任意一个单词即可let arr [nap, teachers, cheaters, PAN, ear, era, hectares]; alert( aclean(arr) ); // nap,teachers,ear 或 PAN,cheaters,era注意两个关键点它们在后面的解法和测试中都会体现大小写不敏感PAN与nap视为同一组变位词注意示例输入中特意混入了大写保留哪个单词不限每组只需留下一个可以是组内任意成员。二、核心思路把单词规范化为「字母排序形式」官方解法 solution.md 的第一句话就点明了核心思想将每个单词拆成字母并排序排序后的结果对所有变位词是相同的。对每个单词做「字母排序」后互为变位词的单词会收敛到同一个规范化形式nap, pan - anp ear, era, are - aer cheaters, hectares, teachers - aceehrst这个规范化字符串就可以作为分组键key。这个思路不限于变位词它是字符串归组类问题如「去重」「找同构词」的通用模式先通过某种确定性变换得到规范形式再以规范形式为键做一次归组。三、Map 解法以排序串为键覆盖式去重官方推荐的完整实现如下与仓库内 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()); } let arr [nap, teachers, cheaters, PAN, ear, era, hectares]; alert( aclean(arr) );整段代码只有四个动作规范化 → 设键 → 遍历 → 取回值。下面逐步拆解。3.1 关键一行toLowerCase().split().sort().join()字母排序由一行方法链完成官方文档将其拆解为多行便于理解let sorted word // PAN .toLowerCase() // pan .split() // [p,a,n] .sort() // [a,n,p] .join(); // anp四个步骤各司其职toLowerCase()先把单词统一转为小写保证PAN与nap得到同一个规范化键anp——这是满足「大小写不敏感」要求的关键split()按空字符串拆分把单词打散为字符数组这样才能调用数组的sortsort()默认按 UTF-16 码元升序排序字母会被排成规范顺序。注意这里没有传比较函数因此只适合处理纯英文字母等简单场景Unicode 变体的注意事项见第五节join()把排序后的数组拼回字符串得到规范化键。3.2 覆盖语义map.set(sorted, word)自动去重接下来map.set(sorted, word)把单词存入以规范化键命名的槽位map.set(sorted, word);这里利用了Map的一个关键特性——同键写入是覆盖式的。当后面再次遇到具有相同排序形式的单词时例如先存了nap又遇到PAN两者键都是anpset会用新值覆盖旧值。因此遍历完整个数组后每个规范化键最多只对应一个单词变位词组天然被压缩成单元素。官方解法原文对此的表述是如果之后再次遇到具有相同字母排序形式的单词它会在 Map 中覆盖同键下的旧值。所以我们总能保证每个字母形式最多对应一个单词。这正是Map相比「先收集全组再手动去重」的优雅之处去重不再需要额外的includes或find检查归组与去重由键的覆盖语义一步完成。3.3 取回结果Array.from(map.values())最后一行把结果取回数组return Array.from(map.values());map.values()返回一个按插入顺序迭代值即单词本身的可迭代对象键排序串在此处不再需要Array.from(...)把这个可迭代对象转换为普通数组正是aclean需要的返回值类型。关于Map的遍历方法keys()/values()/entries()及其保持插入顺序的特性可参见本节主文章 Map and Set 中「Iteration over Map」部分的详细介绍。四、另一种解法用普通对象代替 Map官方解法还给出了一条等价路径因为规范化键是字符串普通对象同样可以作为「字符串键 → 单词」的映射使用function aclean(arr) { let obj {}; for (let i 0; i arr.length; i) { let sorted arr[i].toLowerCase().split().sort().join(); obj[sorted] arr[i]; } return Object.values(obj); } let arr [nap, teachers, cheaters, PAN, ear, era, hectares]; alert( aclean(arr) );两种写法一一对应环节Map 版本对象版本建容器let map new Map()let obj {}循环方式for (let word of arr)for (let i 0; i arr.length; i)写入map.set(sorted, word)obj[sorted] arr[i]取结果Array.from(map.values())Object.values(obj)两者行为等价对象的同名属性赋值同样是覆盖式的Object.values(obj)也能直接取回所有保留的单词。官方文档给出的取舍建议很明确这里也可以用普通对象代替 Map因为键是字符串。什么时候选哪个需要键为任意类型对象、数字、布尔等、或需要size、has、delete等便捷方法时选Map本任务键恰好是字符串对象写法更轻量。Map与Object的能力差异可参考 Map and Set 中的 Summary 对比。五、仓库测试验证两组断言锁定行为仓库为该任务配备了可运行测试 test.js与 solution.js 同目录用 Mocha 的describe/it/assert从两个维度验证aclean断言一每组变位词只保留一个it(returns exactly 1 word from each anagram set, function() { let arr [nap, teachers, cheaters, PAN, ear, era, hectares]; let result aclean(arr); assert.equal(result.length, 3); // 三组变位词 - 三个元素 assert.equal(intersection(result, [nap, PAN]).length, 1); // nap/PAN 组只留 1 个 assert.equal(intersection(result, [teachers, cheaters, hectares]).length, 1); assert.equal(intersection(result, [ear, era]).length, 1); });其中intersection是测试文件自带的辅助函数用filterincludes计算两个数组的交集元素数量。断言精确刻画了「每组恰好留一个」的语义。断言二大小写不敏感it(is case-insensitive, function() { let arr [era, EAR]; assert.equal(aclean(arr).length, 1); });era与EAR经toLowerCase()后得到同一规范化键aer最终只保留一个单词。这两个断言恰好与任务文档 task.md 中的示例输入和「大小写不敏感」要求一一对应是解法正确性的直接代码级证据。六、边界情况与复杂度边界情况空字符串与单字母.split()得[]sort()后仍为空数组join()得一切空串会归到同一个键单字母单词的排序形式就是它自己。这两种情况都能被上述代码正确处理。大小写混合toLowerCase()保证PAN、Pan、nap统一。非英文字母 / Unicodesort()默认按 UTF-16 码元排序对带重音字符如é或需要规范化如fi连字、组合字符的文本排序结果可能不够直观若业务场景需要可额外考虑用比较函数或 Unicode 规范化做键但这不是本任务的要求范围。复杂度从代码结构可以推断aclean的时间开销主要来自两处——每个单词做一次O(k log k)的排序k 为单词平均长度以及整个数组的O(n)次set操作因此总体时间复杂度为O(n · k log k)空间复杂度为O(n)Map 中最多存 n 个键值对。相比「对每个词再线性扫描已收集单词」的朴素做法按键归组避免了二次方级别的重复比较。七、小结一个可复用的「规范化键」模式aclean这道题的解法虽然短却浓缩了两个可迁移到真实工程的知识点规范形式canonical formsplit → sort → join把「字母集合相同但顺序不同」的单词归一为同一个键这是字符串归组问题的通用预处理手段Map 的覆盖式键值语义map.set(key, value)遇同键自动覆盖天然实现「每组取一」配合Array.from(map.values())把结果还原成数组。同时仓库中的 solution.md、solution.js 与 test.js 三者共同构成了「任务 → 实现 → 验证」的完整闭环也是本项目所有练习任务的标准组织方式参见 01-array-unique-map 同构的任务目录。建议读者在本地以node直接运行 test.js 与 solution.js观察两组断言全部通过即可确认对本题语义的理解无误。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐30 Seconds of Interviews 算法实战用 JavaScript 将数组中的变位词Anagram分组输出30 Seconds of Interviews 算法实战用 JavaScript 将数组中的变位词Anagram分组输出 导读 本文基于 30 Seco教程前端终极 Modern JavaScript Cheatsheet掌握 map、filter、reduce 的完整指南终极 Modern JavaScript Cheatsheet掌握 map、filter、reduce 的完整指南 Modern JavaScript CheJavaScript 数组区间过滤实战用 filter 实现 filterRange 且不改动原数组Modern JavaScript TutorialJavaScript 数组区间过滤实战用 filter 实现 filterRange 且不改动原数组Modern JavaScript Tutorial文档/教程前端上一篇CVAT AI自动标注怎么用数据标注完整实操指南下一篇FakeLocationAndroid应用级虚拟定位完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Godot 动画状态机播放控制器 AnimationNodeStateMachinePlayback 完全指南

Godot 动画状态机播放控制器 AnimationNodeStateMachinePlayback 完全指南

文档教程游戏开发 【免费下载链接】godot-docs Godot Engine official documentation 项目地址: https://gitcode.com/GitHub_Trending/go/godot-docs 点击查看 免费下载 AnimationNodeStateMachinePlayback 是 Godot 引擎中用于程序化控制 AnimationTree 状态机&a…

📅 2026/10/3 8:26:48
FinRobot 财富管理技能实战:基于 SKILL.md 的 Client Review Prep 客户会议筹备工作流

FinRobot 财富管理技能实战:基于 SKILL.md 的 Client Review Prep 客户会议筹备工作流

人工智能AI Agent金融科技AI 应用大模型RAG 【免费下载链接】FinRobot FinRobot: An Open-Source AI Agent Platform for Financial Applications using Large Language Models 项目地址: https://gitcode.com/GitHub_Trending/fi/FinRobot 点击查看 免费下载 导读…

📅 2026/10/3 8:26:48
ZeroTermux 内置 bzgrep 命令详解:在 .bz2 压缩包内直接进行正则搜索

ZeroTermux 内置 bzgrep 命令详解:在 .bz2 压缩包内直接进行正则搜索

移动开发开发工具 【免费下载链接】ZeroTermux 项目地址: https://gitcode.com/GitHub_Trending/ze/ZeroTermux 点击查看 免费下载 bzgrep 是 ZeroTermux 内置 Linux 命令手册中收录的一条核心压缩检索命令:它允许你不用先解压,直接在 .bz2 …

📅 2026/10/3 8:21:48
MORE NEWS

更多资讯

📰

没有明确项目标题,技术博文如何保证内容质量?

当前输入的项目标题为“【无标题】”,且热搜词、网络热词、标题网络搜索结果均为空。由于博文生成需要以【项目标题】为核心锚点,提取核心领域、潜在需求、技术点与应用场景,目前缺少可拆解的有效信息,我无法在保证内容质量与紧贴…

📰

YOLO实战全链路指南:从算法演进到T4部署避坑

1. 这不是“又一个YOLO教程”——而是你真正能跑通、调得动、部署出去的实战路线图YOLO。这两个字母在CV圈里,已经不是缩写,而是一种条件反射:看到它,你就知道接下来要面对的是anchor设计、损失函数调试、mAP波动、显存爆炸、Tens…

📰

AI应用框架与AI平台怎么选?智能体开发的关键决策指南

最近把 AI 应用程序框架和 AI 平台放在一起对比,是我被问得最多的问题之一。很多做 AI 智能体(Agent)的朋友一开口就是:我该学 LangChain,还是直接用扣子或者 Dify?说实话,这个问题本身就藏着一…

📰

YOLO工程落地实战:从模型调优到TensorRT部署全链路

1. 这不是“又一个YOLO教程”,而是一份能让你真正跑通、调优、落地的工程实践手记你点开这个标题,大概率是被“100集”“保姆级”“小白友好”这些词吸引来的。但我想先说清楚:如果你期待的是那种“打开IDE,复制粘贴三行代码&…

📰

西瓜书自学指南:从算法推导到项目实战的机器学习路线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Docker指令体系实战拆解:从安装、docker run到compose编排

学Docker最绕不开的就是那一堆指令。我遇到很多朋友,折腾了半天Docker,下载倒是搞定了,结果一上来就被docker run这一串参数搞得晕头转向。尤其是从Windows环境入门的朋友,装个Docker Desktop就够呛,好不容易装好了&am…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬