手寫題:9道字串類高頻面試題

尋找海藍96發表於2019-09-12

本文來源於筆者的開源專案前端面試與進階指南

手寫題:9道字串類高頻面試題

點選關注本公眾號獲取文件最新更新,並可以領取配套於本指南的 《前端面試手冊》 以及最標準的簡歷模板.

解析 URL Params 為物件

let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
parseParam(url)
/* 結果
{ user: 'anonymous',
  id: [ 123, 456 ], // 重複出現的 key 要組裝成陣列,能被轉成數字的就轉成數字型別
  city: '北京', // 中文需解碼
  enabled: true, // 未指定值得 key 約定為 true
}
*/

複製程式碼
function parseParam(url) {
  const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 將 ? 後面的字串取出來
  const paramsArr = paramsStr.split('&'); // 將字串以 & 分割後存到陣列中
  let paramsObj = {};
  // 將 params 存到物件中
  paramsArr.forEach(param => {
    if (/=/.test(param)) { // 處理有 value 的引數
      let [key, val] = param.split('='); // 分割 key 和 value
      val = decodeURIComponent(val); // 解碼
      val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判斷是否轉為數字

      if (paramsObj.hasOwnProperty(key)) { // 如果物件有 key,則新增一個值
        paramsObj[key] = [].concat(paramsObj[key], val);
      } else { // 如果物件沒有這個 key,建立 key 並設定值
        paramsObj[key] = val;
      }
    } else { // 處理沒有 value 的引數
      paramsObj[param] = true;
    }
  })

  return paramsObj;
}

複製程式碼

模板引擎實現

let template = '我是{{name}},年齡{{age}},性別{{sex}}';
let data = {
  name: '姓名',
  age: 18
}
render(template, data); // 我是姓名,年齡18,性別undefined

複製程式碼
function render(template, data) {
  const reg = /\{\{(\w+)\}\}/; // 模板字串正則
  if (reg.test(template)) { // 判斷模板裡是否有模板字串
    const name = reg.exec(template)[1]; // 查詢當前模板裡第一個模板字串的欄位
    template = template.replace(reg, data[name]); // 將第一個模板字串渲染
    return render(template, data); // 遞迴的渲染並返回渲染後的結構
  }
  return template; // 如果模板沒有模板字串直接返回
}

複製程式碼

轉化為駝峰命名

var s1 = "get-element-by-id"

// 轉化為 getElementById
複製程式碼
var f = function(s) {
    return s.replace(/-\w/g, function(x) {
        return x.slice(1).toUpperCase();
    })
}

複製程式碼

查詢字串中出現最多的字元和個數

例: abbcccddddd -> 字元最多的是d,出現了5次

let str = "abcabcabcbbccccc";
let num = 0;
let char = '';

 // 使其按照一定的次序排列
str = str.split('').sort().join('');
// "aaabbbbbcccccccc"

// 定義正規表示式
let re = /(\w)\1+/g;
str.replace(re,($0,$1) => {
    if(num < $0.length){
        num = $0.length;
        char = $1;        
    }
});
console.log(`字元最多的是${char},出現了${num}次`);

複製程式碼

字串查詢

請使用最基本的遍歷來實現判斷字串 a 是否被包含在字串 b 中,並返回第一次出現的位置(找不到返回 -1)。

a='34';b='1234567'; // 返回 2
a='35';b='1234567'; // 返回 -1
a='355';b='12354355'; // 返回 5
isContain(a,b);

複製程式碼
function isContain(a, b) {
  for (let i in b) {
    if (a[0] === b[i]) {
      let tmp = true;
      for (let j in a) {
        if (a[j] !== b[~~i + ~~j]) {
          tmp = false;
        }
      }
      if (tmp) {
        return i;
      }
    }
  }
  return -1;
}

複製程式碼

實現千位分隔符

// 保留三位小數
parseToMoney(1234.56); // return '1,234.56'
parseToMoney(123456789); // return '123,456,789'
parseToMoney(1087654.321); // return '1,087,654.321'

複製程式碼
function parseToMoney(num) {
  num = parseFloat(num.toFixed(3));
  let [integer, decimal] = String.prototype.split.call(num, '.');
  integer = integer.replace(/\d(?=(\d{3})+$)/g, '$&,');
  return integer + '.' + (decimal ? decimal : '');
}

複製程式碼

正規表示式(運用了正則的前向宣告和反前向宣告):

function parseToMoney(str){
    // 僅僅對位置進行匹配
    let re = /(?=(?!\b)(\d{3})+$)/g; 
   return str.replace(re,','); 
}
複製程式碼

判斷是否是電話號碼

function isPhone(tel) {
    var regx = /^1[34578]\d{9}$/;
    return regx.test(tel);
}

複製程式碼

驗證是否是郵箱

function isEmail(email) {
    var regx = /^([a-zA-Z0-9_\-])+@([a-zA-Z0-9_\-])+(\.[a-zA-Z0-9_\-])+$/;
    return regx.test(email);
}

複製程式碼

驗證是否是身份證

function isCardNo(number) {
    var regx = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
    return regx.test(number);
}

複製程式碼

參考:


公眾號

想要實時關注筆者最新的文章和最新的文件更新請關注公眾號程式設計師面試官,後續的文章會優先在公眾號更新.

簡歷模板: 關注公眾號回覆「模板」獲取

《前端面試手冊》: 配套於本指南的突擊手冊,關注公眾號回覆「fed」獲取

2019-08-12-03-18-41

相關文章