拓冰建站拓冰建站
首页 / 资讯中心 / 正文

freeCodeCamp 每日编程挑战解析:用 JavaScript 实现 Consonant Case 字符串转换(Challenge 163)

freeCodeCamp 每日编程挑战解析用 JavaScript 实现 Consonant Case 字符串转换Challenge 163【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCampfreeCodeCamp 开源仓库中的「每日编程挑战」Daily Coding Challenges为学习者提供了一年 365 道短小精悍的算法练习题。本文聚焦其中的Challenge 163: Consonant Case完整讲解题目规则、hints 测试断言、参考解法与多种实现思路并基于仓库源码剖析这道题从课程 Markdown 到线上答题系统的完整流转链路schema 校验 → GraphQL 抓取 → 数据库 seed → API 下发让读者既能独立解出题目也能理解它在 freeCodeCamp 技术栈中的真实位置。题目速览Challenge 163 的核心规则题目位于仓库的 daily-coding-challenges-javascript 挑战块challengeType: 28属于每日编程挑战类型。题目要求实现函数toConsonantCase(str)将传入的「变量名」字符串按以下三条规则转换所有辅音字母转为大写consonant → uppercase所有元音字母a、e、i、o、u不区分大小写转为小写所有连字符-转为下划线_。题目对除字母和连字符之外的其他字符如_、~、数字、符号没有提出任何转换要求——它们应当原样保留这正是该题容易被忽略的隐藏约束也是官方参考解法中最值得学习的细节。题目同时存在于 JavaScript 与 Python 两个语言版本的挑战块见 dev-playground.json其中并列定义了daily-coding-challenges-javascript与daily-coding-challenges-python两道同题号题目的标题与描述必须完全一致在 helpers.ts 中有专门的校验逻辑。读懂 hints四个测试断言的含义题目以# --hints--形式给出了 4 个assert.equal断言它们既是评判依据也精确划定了函数的行为边界。逐条分析输入期望输出考察点helloworldHeLLoWoRLD全小写输入辅音大写、元音小写HELLOWORLDHeLLoWoRLD全大写输入先做大小写归一化_hElLO-WOrlD-_HeLLo_WoRLD_大小写混合 连字符转下划线_~-generic_~-variable_~-name_~-here-~__~_GeNeRiC_~_VaRiaBLe_~_NaMe_~_HeRe_~_特殊字符_、~原样保留连字符全部转换最后一个用例揭示了最关键的行为细节_~-generic_~-...转换后变成_~_GeNeRiC_~_...——输入中_~之后紧跟-输出里_~保持原样而-变为_字符串整体长度不变只发生了字符级替换。函数必须对字符串进行逐字符处理而不是基于单词分割或正则整体替换否则很容易在特殊字符边界上出错。这些 hint 最终会被解析为tests数组写入数据库。根据 challenge-schema.js 的定义tests数组中的每个元素是{ text, testString }结构——text是给人看的说明文字testString是真正在浏览器中执行断言用的代码字符串也就是上文中assert.equal(...)那几行。从零实现官方参考解法逐行拆解题目给出的参考解法# --solutions--如下function toConsonantCase(str) { const vowels aeiouAEIOU; let result ; for (let char of str) { if (char -) { result _; } else if (/[a-zA-Z]/.test(char)) { if (vowels.includes(char)) { result char.toLowerCase(); } else { result char.toUpperCase(); } } else { result char; } } return result; }逐行拆解其设计逻辑const vowels aeiouAEIOU元音集合同时包含大小写。这样后续只需判断「当前字符是否在元音集合中」无需先归一化大小写。for (let char of str)for...of逐字符迭代天然满足「非字母、非连字符字符原样保留」的要求。这是解法正确性的关键——它按字符索引遍历而不是按单词或按空白分割。分支一char -先处理连字符直接拼接_。分支二/[a-zA-Z]/.test(char)用正则判定是否为英文字母是字母且非元音 →toUpperCase()大写是元音 →toLowerCase()小写。分支三隐式 else数字、下划线、波浪号、空格等其他字符直接原样拼接。return result返回拼接结果不修改原字符串函数无副作用。该解法的核心思想可以概括为**「先判类型再定大小写」**先区分三类字符连字符 / 字母 / 其他再在字母类中区分元音与辅音。分支顺序决定了语义——连字符优先于字母判断而字母判断又优先于「原样保留」任何字符都必然落入恰好一个分支。思路拓展三种等价实现对比除了官方解法这道题还有多种等价写法。下面给出两种便于理解题目的本质与取舍方案一字符编码区间判断避免正则function toConsonantCase(str) { const vowels new Set(aeiouAEIOU); let result ; for (const char of str) { const isLetter /^[a-z]$/i.test(char); if (char -) { result _; } else if (isLetter !vowels.has(char)) { result char.toUpperCase(); } else if (isLetter vowels.has(char)) { result char.toLowerCase(); } else { result char; } } return result; }方案二正则整体替换注意边界陷阱function toConsonantCase(str) { return str .replace(/-/g, _) .replace(/[aeiou]/gi, m m.toLowerCase()) .replace(/[b-df-hj-np-tv-z]/gi, m m.toUpperCase()); }方案二代码最简洁但有一个需要注意的缺陷/[b-df-hj-np-tv-z]/gi这类辅音区间写法依赖 ASCII 码表连续性b–d、f–h、j–n、p–t、v–z 的间隔恰好跳过元音虽然对本题目字母集有效却容易在改造成其他字符集时出错。相比之下逐字符扫描 显式元音集合的方案可读性与可维护性最佳这也是官方选择它的原因。复杂度分析三种方案的时空复杂度均为 O(n)n 为输入字符串长度。for...of与includes/Set.has都是线性扫描若追求极端性能可将元音集合换为Set使单字符查询摊还 O(1)但对普通变量名长度而言差异可忽略。解出题目后它如何进入每日答题系统这道 Challenge 163 并不是孤立的一道题它是「每日编程挑战」产品功能的一环。仓库中从课程文件到线上答题的完整链路如下课程 Markdown 是唯一内容源题目描述、hints、seed 代码、官方解法全部定义在 694596b0585c11170ac7c7fb.md 中并通过 challenge-schema.js 做结构校验challengeType取值 0–33、tests数组必须含text与testString等。Gatsby GraphQL 抓取dev-playground超级块superblock下定义了 JavaScript 与 Python 两个挑战块。种子脚本通过 fetchChallenges 向运行中的 client 的___graphql端点发起 GraphQL 查询按superBlock: dev-playground、block: daily-coding-challenges-${language}过滤并按challengeOrder排序抓取全部挑战。JS 与 Python 配对合并combineChallenges 将同题号的 JS/Python 挑战合并为一条记录——题号取自数组下标challengeNumber: i 1故 Challenge 163 即第 163 条title去掉Challenge 163: 前缀描述经removeSection去掉解析器添加的section包装测试与代码文件则按语言分别挂到javascript/python字段。按天排期写入 MongoDBseed-daily-challenges.ts 以2025-08-11为起始日每道题向后顺延一天START_DATE.getTime() i * ONE_DAY_IN_MS脚本还硬编码了EXPECTED_CHALLENGE_COUNT 365用于数量自检并冻结起始日期防止发布后误改。因此 Challenge 163 对应的自然日是2025-08-11 162 天。API 按日期下发API 层提供 daily-coding-challenge 路由包括/daily-coding-challenge/date/:date按YYYY-MM-DD查询、/day/:day按MM-DD查询、/today、/month/:month、/all、/newest六个公开 GET 接口。所有查询都以「美国中部时区的今天」为截止边界未来日期的题目不会提前泄露——Challenge 163 也要到其排期日期当天才可访问。响应结构与客户端消费单题响应结构在 daily-coding-challenge.ts 的 schema 中定义包含id、date、challengeNumber、title、description以及javascript/python两组{ tests, challengeFiles }。客户端侧 widget.tsx 与 calendar.tsx 负责展示与日历导航helpers.ts 则提供getTodayUsCentral、formatDate、formatDisplayDate等日期工具——所有「今天」均以America/Chicago时区计算。从这条链路可以看出学习者答题时填写的toConsonantCase实现会被浏览器中的测试运行器执行而其依据正是题目 Markdown 中那 4 条assert.equal而「今天该做哪道题」则由种子脚本的日期排期与 API 的时区边界共同决定。测试驱动验证确保实现通过全部断言完成实现后可以把它直接放进浏览器控制台或 Node.js 环境用题目提供的 4 个断言验证// 粘贴你的实现 function toConsonantCase(str) { /* ... */ } // 运行题目 hints const cases [ [helloworld, HeLLoWoRLD], [HELLOWORLD, HeLLoWoRLD], [_hElLO-WOrlD-, _HeLLo_WoRLD_], [_~-generic_~-variable_~-name_~-here-~_, _~_GeNeRiC_~_VaRiaBLe_~_NaMe_~_HeRe_~_] ]; let passed 0; for (const [input, expected] of cases) { const actual toConsonantCase(input); const ok actual expected; console.log(${ok ? PASS : FAIL} toConsonantCase(${JSON.stringify(input)}) ${JSON.stringify(actual)}); if (ok) passed; } console.log(${passed}/${cases.length} tests passed);全部 4 条通过即说明实现满足题目约束。在此基础上可以再做一轮自测验证边界行为空字符串toConsonantCase()应返回for...of对空串不产生任何迭代。无字母输入toConsonantCase(-_~123)应返回__~123——连字符被替换其余原样。非英文字母带重音的字符如é不属于[a-zA-Z]应原样保留。小结Challenge 163 是一道典型的「字符级转换」题目其考点集中于三点大小写归一化无论输入是全大写、全小写还是混合、字符分类处理辅音 / 元音 / 连字符 / 其他四类互斥分支以及对非字母字符的保真。官方参考解法用「元音集合 正则判定 逐字符遍历」给出了简洁可靠的实现而将这道题放回仓库语境中它又展示了 freeCodeCamp 内容与工程体系的联动方式——一份 Markdown 定义题目GraphQL 抓取配对种子脚本排期入库API 按时下发最终在浏览器中完成一次真实的算法训练。如果你还想继续练习同系列题目仓库中同一挑战块还包含Challenge 15: camelCase6821ebce237de8297eaee790.md、Challenge 114: Camel to Snake69162d64f96574d9bb629eff.md、Challenge 140: SCREAMING_SNAKE_CASE69272dcf1c24b44fd79137c3.md等同属命名规范转换主题的练习题它们的解题思路与本题目一脉相承。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门