来自codewars中的面试题,正则表达式与replace的天然结合(多解法解题)
前言
今天我们一起来讨论一下一道来自codewars中抽取的面试题,相信拿下这道题目之后,大家在遇中小厂面试时同类型的题目便能得心应手了。
面试题1
编写一个函数,,它接收一个10个整数的数组。该函数以(123)456-7890 返回电话字符串
解法1(字符串拼接)
function createPhoneNumber(nums) {
return '(' + nums[0] + nums[1] + nums[2] + ')'
+ nums[3] + nums[4] + nums[5] + '-'
+ nums[6] + nums[7] + nums[8] + nums[9];
}
console.log(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]));
可以看到,这种解法就是一种简单的字符串拼接
,题目虽然解答了,但是却无法虏获面试官的芳心。但是这种解法可以为我们打牢基础,提升代码编写能力
解法2(replace方法)
function createPhoneNumber(nums) {
let format = "(xxx) xxx-xxxx";
for (let i = 0; i < nums.length; i++) {
format = format.replace("x", nums[i]);
}
return format;
}
console.log(createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]));
可以看到,这种方法运用到了replace方法
,首先我们定义了一个模板字符串,再通过replace方法对模板内容进行一个简单的替换,同样的,题目虽解,心却未得,我们不妨对题目进一步深化。
面试题2
- like 系统
- [] “no one like this”
- ["Tim"] "Tim likes this"
- ["Tim", "John"] "Tim and John like this"
- ["Tim", "John", "Mark"] "Tim, John and Mark like this"
- ["Tim", "John", "Mark", "Jess"] "Tim, John and 2 others like this"
分析:like系统中,如果数组空,则无人喜欢,1人则输出人名,两人三人依次,四人则输出两人名字和剩余喜欢人数
解法1(字符串模板变量/字符串拼接)
- 可以看到,这里存在五个分支,如果依然使用if、else做条件则显得不那么合适了,超过3个分支就不用ifelse了,因此我们可以选择
switch case结构
箭头函数
,()=>{},简洁明了,如果只接收一个参数,我们可以直接省略小括号,如果函数体中只存在一行代码,我们可以省略花括号。
const like = (names) => {
switch (names.length) {
case 0:
return "no one likes this";
break;
case 1:
return `${names[0]} likes this`;
break;
case 2:
return `${names[0]} and ${names[1]} like this`;
break;
case 3:
return `${names[0]}, ${names[1]} and ${names[2]} like this`;
break;
default:
return `${names[0]}, ${names[1]} and ${names.length - 2} others like this`
}
}
- 在这种解法中,我们看到其中还使用了
字符串模板,往字符串中添加变量,需要将整个字符串的引号改成前引号,变量可以通过$加花括号的形式添加。
当然这里我们可以不用字符串模板的方式,可以直接用字符串拼接,将变量拼接进去。
解法2(正则表达式与replace的天然结合)
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) {
console.log(val, '----------------------');
return val === '{name}' ? names.shift() : names.length;
})
}
console.log(likes(['Peter', 'Paul', 'Mary', 'John', 'Paul']));
可以看到,在这种解法中我们首先定义了一个模板,因为我们存在5种情况,我们通过Math.min
比较2者的大小,选择较小者,通过这种方式我们就取得了index下标,通过下标我们可以访问到我们定义的templates模板中的值,是1个人的情况?还是2个人的情况?
注意点:
- 正则表达式是一种强大的模板匹配工具,可以通过
/正则表达式模式/修饰符
的方式创建正则对象,在这个例子中,我们就是匹配了模板中的{name},修饰符g则为global,匹配全局的{name},| 为或者 replace(x,x)
,replace方法是用后者替换前者,但是如果后者是一个函数并且接收形参的情况,则这个形参为默认传入前者names.shift()
,names为一个数组,数组的shift方法是弹出栈顶元素并接收一个返回值,值为栈顶元素。- 三元运算符,判断匹配到的是不是{name},是则将数组第一个人弹出并返回,替换模板中的{name},第二次依次,第三次则发现没有{name}了,剩下是{n},则三元运算符取后者,获取数组目前长度,前面2次已经弹出了2个人,因此不需要对数组长度-2,然后将这个返回值替换{n}。
断点调试
我们可以通过打断点的方式,对我们的程序进行调bug,理解程序的执行过程,发现问题所在。可以将我们的js代码引入html,然后在浏览器中调试
- 打开浏览器(如 Chrome)的开发者工具(通常按 F12 键)。
- 在“Sources”(源)选项卡中找到对应的 JavaScript 文件,在你想要设置断点的代码行处点击即可设置断点。
通过这种方式,我们可以清晰看到我们定义的每一个变量,每一个方法,现在执行到什么位置,什么程度,变量存放的是什么。有利于提升我们的代码能力。
小结
在 JavaScript 中,正则表达式与replace
方法天然结合,可以实现强大的字符串替换功能。replace
方法的语法为string.replace(regexp, replacement)
,其中regexp
是一个正则表达式对象或字符串,replacement
是一个字符串或函数。
let str = "Hello 123 World!";
let newStr = str.replace(/\d/g, function(match) { return '*'; });
console.log(newStr);
如果replacement
参数是一个函数,那么对于每个匹配的子串,都会调用该函数,并将函数的返回值作为替换后的内容。match
是一个回调函数的参数。当使用 replace()
方法结合正则表达式进行字符串替换时,可以提供一个回调函数作为第二个参数。这个回调函数会在每次匹配到正则表达式时被调用,并将匹配的结果作为参数传递给回调函数。
转载自:https://juejin.cn/post/7377334520687247369