众安笔试3.29复盘

307 阅读2分钟

1.连接线转驼峰

可惜了这道题,去年小红书面过同样的题,当初忘记复盘了,直到现在都还不是很顺畅,想想都这么久了,真是可怕

献献丑,看看昨天只A了50%的屎山代码

function camelCase( str ) {
    // write code here
    let count = [];
    let res;
    for (let i = 0; i < str.length; i++) {
        if (str[i] === '-') {
            count.push(i)
        }
    }
    let newStr = str.replace(/-/g, '')

    for (let j = 0; j < count.length; j++) {
        let item;
        if(j==0){
            item = count[j];
        }
        console.log(item)
        newStr = newStr.replace(newStr[item], newStr[item].toUpperCase());
    }
    return newStr
}

我的意思是,想先找出字符串str中所有的-,记录每一个-的索引位置,然后把-后面的那个字母替换成小写字母,再删去-即可

如果字符串中只存在一个-,那么这段代码是生效的,如果字符串中存在多个-,就出bug了。。。

本质上都是我没有对replace方法理解透彻,才走了这么多弯路

replace方法

语法

str.replace(regexp|substr, newSubStr|function) 注意到,第二个参数是可以传函数进去的(话说我之前不知道啊。。。

function camelCase( str ) {
    function upper(all,letter){
        console.log(all);// all为RegExp匹配到的所有项
        return letter.toUpperCase();
    }
    let res = str.replace(/-(\w)/g,upper)
    return res;
}

let s = camelCase("-background-ima-gj");
console.log(s)

upper接收两个参数,第一个参数是replace根据/-(\w)/g匹配到的所有项,第二个参数则是-后面匹配到的字母

为了测试我又多传了几个参数进去

function upper(all,letter,x,y){
    console.log(all,letter,x,y);// all为RegExp匹配到的所有项
    return letter.toUpperCase();
}

输出如下

image.png

可以看到,输出的四个参数分别代表

第一个参数:/-(\w)/g

第二个参数:(\w)

第三个参数:/-/的索引位置

第四个参数:原字符串str

这么好的东西不用??非得写for循环???(我真傻

事到如今只能感叹,妙哉,妙哉~

注意事项

如果是str.replace(substr, newSubStr)的话,只会执行一次匹配

也就是说,会找到第一符合的substr替换成newSubStr,往后哪怕有符合的substr也不会再执行替换了

如果是str.replace(regexp, function)的话,会执行全匹配,因为每次匹配都会调用第二个回调函数。这个正则所匹配的内容会被第二个参数的返回值替换掉

2.版本号排序

leetcode原题在这边,不过笔试中,是改编题

大同小异了,直接来看力扣的题吧

题目

给你两个版本号 version1 和 version2 ,请你比较它们。

版本号由一个或多个修订号组成,各修订号由一个 '.' 连接。每个修订号由 多位数字 组成,可能包含 前导零 。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0 ,下一个修订号下标为 1 ,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。

比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较 忽略任何前导零后的整数值 。也就是说,修订号 1 和修订号 001 相等 。如果版本号没有指定某个下标处的修订号,则该修订号视为 0 。例如,版本 1.0 小于版本 1.1 ,因为它们下标为 0 的修订号相同,而下标为 1 的修订号分别为 0 和 1 ,0 < 1 。

输入:version1 = "1.01", version2 = "1.001" 输出:0 解释:忽略前导零,"01" 和 "001" 都表示相同的整数 "1"

题目看着又臭又长又吓人,虽然是中等题,但其实并不难

思路

通过'.'把字符串分割成字符串数组,对比两个数组同一层数字大小即可

需要注意的是,越界问题怎么解决

短的那个数组,如果遍历到undefined了,那就补零,填充0,再对比

题解

来看题解

/**
 * @param {string} version1
 * @param {string} version2
 * @return {number}
 */
var compareVersion = function(version1, version2) {
    let vs1 = version1.split('.').map(item => item - 0);
    let vs2 = version2.split('.').map(item => item - 0);
    let i = 0;

    while (i < vs1.length || i < vs2.length) {
        //补0
        if (!vs1[i]) {
            vs1[i] = 0
        }
        if (!vs2[i]) {
            vs2[i] = 0
        }
        if (vs1[i] > vs2[i]) {
            return 1;
        } else if (vs1[i] < vs2[i]) {
            return -1;
        } else {
            i++;
        }
    }
    return 0
};

3.字符串转数组、去重、排序

题目

给一个字符串'[1,2,[4,3],[5,1,3]'需要把这个字符串数组转为一维数组,然后按升序排序,还要求去重

这题AC了,我就没记录下来怎么写的

我本来想找有没有原生的API能够直接将字符串数组转成数组的,这样就能用flat、sort、new Set()一波操作直接实现

我发现好像没有这样的API(也可能我的知识盲区

思路

所以我的思路大概是这样的:

  1. 建立一个新数组,遍历字符串,如果是NaN的话(比如','、'['这种),就不推入数组
  2. 然后得到一个[1,2,4,3,5,1,3]这样的一维数组
  3. 排序不用我说了吧sort((a,b)=>{return b-a;})
  4. 去重Array.from(new Set(arr))

整体来说还是比较简单的,稍微卡我的第一步,有个需要注意的细节,就是处理字符串的时候我用的是隐式转换,判断遍历到的每一个小字符子串是不是非数字类型,不是的话才推入新数组str[i]-0,如果是'1'-0的话会隐式转换为数字1

字符串中存在空格,那么遍历到空格时,就变成了' '-0默认转化为数字0,那么此时就会从原字符数组中凭空生出一个数字0来

所以这边需要提前处理一下,把原字符数组里的空格去掉或者替换为','

haha,反正这边我是取巧了一下替换为',',也就是NaN,不会被推入数组

本文正在参加「金石计划」 欢迎指正~