面试手写第五期

一. 实现一个函数用来对 URL 的 querystring 进行编码

const data = {
    
    
  a: 3,
  b: 4,
  c: 5,
};
function stringify(data) {
    
    
  const pairs = Object.entries(data);
  const qs = pairs
    .map(([k, v]) => {
    
    
      let noValue = false;
      if (v === null || v === undefined || typeof v === "object") {
    
    
        noValue = true;
      }
      return `${
      
      encodeURIComponent(k)}=${
      
      noValue ? "" : encodeURIComponent(v)}`;
    })
    .join("&");
  return qs;
}
// 对 data 编码后得到 querystring 如下
//=> 'a=3&b=4&c=5'
stringify(data);

二. 如何实现一个数组洗牌函数 shuffle

function shuffle(array) {
    
    
  let len = array.length;
  let _array = [...array];
  while (len) {
    
    
    let index = Math.floor(Math.random() * len--);
    [_array[index], _array[len]] = [_array[len], _array[index]];
  }
  return _array;
}

三. 异步加法的几种方式

串行

function add(a, b) {
    
    
  return Promise.resolve(a + b);
}
async function sum(arr) {
    
    
  let s = arr[0];
  for (let i = 1; i < arr.length; i++) {
    
    
    s = await add(s, arr[i]);
  }
  return s;
}

并行

function add(a, b) {
    
    
  return Promise.resolve(a + b);
}
 
function chunk(list, size) {
    
    
  const l = [];
  for (let i = 0; i < list.length; i++) {
    
    
    const index = Math.floor(i / size);
    l[index] ??= [];
    l[index].push(list[i]);
  }
  return l;
}

async function sum(arr) {
    
    
  if (arr.length === 1) return arr[0];
  const promises = chunk(arr, 2).map(([x, y]) =>
    // 注意此时单数的情况
    y === undefined ? x : add(x, y),
  );
  return Promise.all(promises).then((list) => sum(list));
}

sum([1, 2, 3, 4]).then(res => {
    
    
  console.log(res);
})

四. 实现trim函数

function trim(str = "") {
    
    
  str = String(str);
  let left = 0;
  let right = str.length - 1;
  while (/\s/.test(str[left]) && left < right) {
    
    
    left += 1;
  }
 
  while (/\s/.test(str[right]) && left < right) {
    
    
    right -= 1;
  }
  return str.slice(left, right + 1);
}

五. 求多个数组的交集

function intersection(...args) {
    
    
  return args.reduce((res, cur) => [...new Set(res.filter(item => cur.includes(item)))])
}
console.log(intersection([1, 2, 2], [1, 2, 2], [1, 2]));

六. 手写实现render函数

function get(source, path, defaultValue = undefined) {
    
    
  // a[3].b -> a.3.b -> [a, 3, b]
  const paths = path
    .replace(/\[(\w+)\]/g, ".$1")
    .replace(/\["(\w+)"\]/g, ".$1")
    .replace(/\['(\w+)'\]/g, ".$1")
    .split(".");
  let result = source;
  for (const p of paths) {
    
    
    result = result?.[p];
  }
  return result === undefined ? defaultValue : result;
}
 
function render(template, data) {
    
    
  return template.replace(/{
     
     {\s+([^\s]+)\s+}}/g, (capture, key) => {
    
    
    return get(data, key);
  });
}

七. 驼峰转- -转驼峰

//驼峰转短横线
function toKebabCase(str) {
    
    
  let res = str.replace(/([A-Z])/g, (all, i) => {
    
    
    return "-" + i.toLowerCase();
  });
  if (res.slice(0, 1) === "-") {
    
    
    res = res.slice(1); //去除开头的-
  }
  return res;
}
//短横线转驼峰
function toCamelCase(str) {
    
    
  return str.replace(/-([a-zA-Z])/g, function (all, i) {
    
    
    return i.toUpperCase();
  });
}
 
console.log(toCamelCase("get-element-by-id"));
console.log(toKebabCase("GetElementById"));

八. instanceof实现

function fakeInstanceOf(instance, parent) {
    
    
  if (typeof instance !== "object" && typeof instance !== "function") {
    
    
    return false;
  }
  let proto = instance?.__proto__ || null;
  while (true) {
    
    
    if (proto === null) {
    
    
      return false;
    }
    if (proto === parent.prototype) {
    
    
      return true;
    }
    proto = proto.__proto__;
  }
}

//=> true
console.log(fakeInstanceOf([], Array));
 
//=> true
console.log(fakeInstanceOf([], Object));
 
//=> true
console.log(fakeInstanceOf(x => x, Object));
 
//=> false
console.log(fakeInstanceOf('hello', Object));

九. 组合问题

function combinationGenerator(m, n) {
    
    
  const results = [];
  function backtracking(start, currentComb) {
    
    
    if (currentComb.length === n) {
    
    
      results.push(currentComb.slice());
      return;
    }
    for (let i = start; i <= m; i++) {
    
    
      currentComb.push(i);
      backtracking(i + 1, currentComb);
      currentComb.pop();
    }
  }
  backtracking(1, []);
  return results;
}
console.log(combinationGenerator(3, 2));

十. 字符串分组

function groupAnagrams(strs) {
    
    
  const groups = new Map();
  for (let str of strs) {
    
    
    const sortStr = str.split('').sort().join();
    if (!groups.has(sortStr)) {
    
    
      groups.set(sortStr, []);
    }
    groups.get(sortStr).push(str);
  }
  return Array.from(groups.values());
}

const strings = ['eat', 'tea', 'tan', 'ate', 'nat', 'bat'];
console.log(groupAnagrams(strings));

猜你喜欢

转载自blog.csdn.net/qq_63299825/article/details/135955138