关于CodeWars点赞功能实现代码中replace方法的疑问
拆解CodeWars点赞函数里的replace逻辑,解答你的三个疑问
嘿,作为正在为大学编程打基础的高中生,你能盯着代码抠细节,这习惯真的超棒!我来一步步帮你把这个replace方法里的逻辑掰碎了讲清楚,解决你的三个疑问:
先回顾问题和解决方案
你在CodeWars遇到的是实现Facebook风格的点赞文本功能,要求写一个likes函数,输入点赞者姓名数组,返回对应的展示文本,示例如下:
likes []→ 返回"no one likes this"likes ["Peter"]→ 返回"Peter likes this"likes ["Jacob", "Alex"]→ 返回"Jacob and Alex like this"likes ["Max", "John", "Mark"]→ 返回"Max, John and Mark like this"likes ["Alex", "Jacob", "Mark", "Max"]→ 返回"Alex, Jacob and 2 others like this"
你找到的解决方案代码是这样的:
var names=["Erica", "Steven","Dono", "Erick"]; function likes (names) { var templates = [ 'no one likes this', '{name} likes this', '{name} and {name} like this', '{name}, {name} and {name} like this', '{name}, {name} and {n} others like this' ]; var idx = Math.min(names.length, 4); return templates[idx].replace(/{name}|{n}/g, function (val) { return val === "{name}" ? names.shift() : names.length; }); } var runlikes= likes(names); console.log(runlikes);
你已经搞懂了replace之前的逻辑,现在针对你提出的三个疑问逐个解答:
疑问1:代码怎么拿到Erica、Steven这些名字,又怎么替换{n}的剩余人数?
首先看replace的第一个参数/{name}|{n}/g,这是个正则表达式:
|表示“或者”,意思是匹配{name}或者{n};g是全局匹配标志,会把模板里所有符合的占位符都找出来,一个一个替换。
replace的第二个参数是个回调函数——每次匹配到一个占位符({name}或{n}),就会调用这个函数,把匹配到的内容传给参数val。
- 当匹配到
{name}时,代码调用names.shift():这个方法会把数组的第一个元素取出来返回,同时数组本身会删掉这个元素。比如第一次匹配{name}时,取出Erica;第二次匹配时,取出Steven,这样就依次拿到了需要展示的名字。 - 当匹配到
{n}时,此时names数组里剩下的元素数量就是“其他人数”。比如原数组有4个名字,前面已经用shift()取走2个,剩下2个,所以names.length就是2,正好对应要替换的{n}。
疑问2:代码里的冒号是三元运算符,它的工作机制是什么?
没错,这里的冒号是三元条件运算符的一部分,它是JavaScript里简化版的if-else,语法是:
条件表达式 ? 条件为真时返回的值 : 条件为假时返回的值
放到这段代码里就是:
return val === "{name}" ? names.shift() : names.length;
翻译成大白话就是:
- 先判断当前匹配到的
val是不是等于{name}; - 如果是(也就是要替换成名字),就返回
names.shift()的结果(数组的第一个名字); - 如果不是(那肯定是匹配到
{n}了),就返回names.length(剩余的人数)。
它和下面的if-else代码完全等价,只是写法更简洁:
if (val === "{name}") { return names.shift(); } else { return names.length; }
这种写法特别适合这种二选一的简单逻辑。
疑问3:return val === "{name}"的作用是什么,代码怎么判断什么时候换替换内容?
这个判断的核心作用就是区分当前匹配到的是哪个占位符:
- 当
val等于{name}时,说明我们需要替换成具体的名字,所以调用names.shift()取第一个名字; - 当
val不等于{name}时,结合正则的匹配规则,此时一定是匹配到{n}了,所以就返回剩余的人数。
再举个例子,比如4人及以上的模板:{name}, {name} and {n} others like this,正则会按顺序匹配:
- 第一个
{name}→ 回调返回Erica; - 第二个
{name}→ 回调返回Steven; - 第三个
{n}→ 回调返回此时names的长度(2);
这样替换后就得到了Erica, Steven and 2 others like this,完全符合要求。
内容的提问来源于stack exchange,提问作者Dwika Haryo Radithya
相关产品推荐
相关产品推荐

