1. 1. 第一题
    1. 1.1. 方法一
    2. 1.2. 方法二
  2. 2. 第二题
    1. 2.1. 方法一
    2. 2.2. 方法二
  3. 3. 第三题
    1. 3.1. 方法一
  4. 4. 第四题
    1. 4.1. 方法一
    2. 4.2. 方法二

笔试须知:

  1. 请认真审题,编写的代码尽可能通用,而不限定在给定的用例

  2. 时长限定在1小时以内,提前做完可以知会面试官

  3. 可使用自己喜欢的编辑器和调试工具 ,笔试过程中须共享屏幕,请不要在线查找资料

第一题

完成函数 flatten,接受数组作为参数,数组元素包含整数或数组,函数返回扁平化后的数组

1
2
3
4
function flatten(arr) {
// coading...
}
console.log(flatten([1, [2, [3, 4], 5], 6])); // [1, 2, 3, 4, 5, 6]

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function flatten(arr) {
let resultArr = [];
const _flatten =(arr)=>{
arr.forEach((item) => {
if (Array.isArray(item)) {
const newItem=item.flat()
_flatten(newItem);
} else {
resultArr.push(item);
}
});
}
_flatten(arr)
return resultArr
}

方法二

pop 配合 unshift;shift 配合 push;方法同理;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function flatten(arr) {
if(!Array.isArray(arr)) throw new Error('不是数组');
const result = [];
const _flatten = (childArr) => {
const item = childArr.pop();
if(Array.isArray(item) && item.length) {
_flatten(item);
} else {
result.unshift(item);
}
childArr.length && _flatten(childArr);
}
_flatten(arr);
return result;
}

第二题

实现一个格式化数字的函数 addComma,给数字添加千位分隔符

1
2
3
4
function addComma(num) {
// coading...
}
console.log(addComma(1234)); // 1,234

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function addComma(num) {
const numStr=String(num)
let resultStr="";
if(numStr.length<3){
resultStr=numStr
} else {
const arr=numStr.split("")
const length=numStr.length
const firstN=length%3
const group=Math.ceil(length/3)
for(let i=0;i<group;i++){
if(i==0){
resultStr=numStr.substr(0,firstN)
}else {
const start=firstN+3*(i-1)
resultStr+=","+numStr.substr(start,3)
}
}

}
return resultStr
}

方法二

1
2
3
4
5
6
7
8
9
10
11
12
13
function addComma(num) {
let numstr = `${num}`;
let newStr = numstr.replace(/(\d{3})/g, '$1,'); // '123,4'
let list = newStr.split(','); // ['123', '4']
let lastLength = list[list.length - 1].length; // 1
newStr = numstr.slice(lastLength).replace(/(\d{3})/g, ',$1');
newStr = numstr.slice(0,lastLength) + newStr
if(newStr.startsWith(',')) {
return newStr.slice(1);
}
return newStr;
}
console.log(addComma(1234)); // 1,234

第三题

实现一个sum方法,使sum(x)(y)(z)(…)(a)和sum(x,y,z,… a)返回的结果相同

1
2
3
4
5
6
7
function sum(){
// coading...
}

console.log(sum(1)(2)(3)) // 6
console.log(sum(1, 2, 3)) // 6

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
function sum(...args){
const paramsList = [...args];
function add(...rest) {
paramsList.push(...rest);
return add;
}
add.toString = function() {
const res = paramsList.reduce((a,b) => a + b);
return res;
}
return add;
}

第四题

有一个扁平的数组描述了一系列的地理信息(深度不限于4层,可能有更多),类似于

1
2
3
4
5
6
7
8
9
10
var locationList = [
{ id: 0, name: "中国" },
{ id: 1, pid: 0, name: "广东省" },
{ id: 2, pid: 1, name: "深圳市" },
{ id: 3, pid: 1, name: "广州市" },
{ id: 4, pid: 2, name: "南山区" },
{ id: 5, pid: 3, name: "天河区" }
...
]

其中每个节点的 pid 指向了它所属上级地区。现在要求你把这个数组转换成树状结构

1
2
3
4
5
6
var locationTree = buildLocationTree(locationList);

function buildLocationTree(locationList) {
// coad...
}

其中 locationTree 的结构应该如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
root: {
id: 0,
name: '中国',
subLocations: [
{
id: 1,
pid: 0,
name: '广东省',
subLocations: [
{
id: 2,
pid: 1,
name: "深圳市",
subLocations: [{
id: 4,
pid: 2,
name: "南山区"
}]
},
{
id: 3,
pid: 1,
name: "广州市",
subLocations: [{
id: 5,
pid: 3,
name: "天河区"
}]
},
// ...
]
},
// ...
]
}
}

方法一

直接遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 测试数据
var locationList = [
{ id: 1, pid: 0, name: "广东省" },
{ id: 4, pid: 2, name: "南山区" },
{ id: 0, name: "中国" },
{ id: 2, pid: 1, name: "深圳市" },
{ id: 3, pid: 1, name: "广州市" },
{ id: 5, pid: 3, name: "天河区" },
{ id: 6, name: '美国' },
{ id: 7, name: '英国' },
{ id: 10, pid: 7, name: "伦敦" },
{ id: 11, pid: 7, name: "苏格兰" },
{ id: 12, pid: 6, name: "纽约" },
{ id: 13, pid: 12, name: "时代广场" },
{ id: 14, pid: 6, name: "加州" },
{ id: 15, pid: 6, name: "华盛顿" },
{ id: 16, pid: 6, name: "旧金山" },
{ id: 17, pid: 0, name: "陕西省" },
{ id: 18, pid: 17, name: "西安市" },
{ id: 19, pid: 18, name: "高新区" },
{ id: 20, pid: 18, name: "莲湖区" },
{ id: 21, pid: 17, name: "商洛市" },
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function buildLocationTree(locationList) {
const treeList = [];
const forEach = (arr, parent = {id:undefined}) => {
arr.forEach((item,index) => {
if(item.pid !== undefined && item.pid === parent.id) {
parent.subLocations ? parent.subLocations.push(item) : parent.subLocations = [item];
arr.splice(index,1);
forEach(arr,item);
forEach(arr,parent);
} else if(item.pid === undefined) {
treeList.push(item);
arr.splice(index,1);
forEach(arr,item);
}
})
}
forEach(locationList);
return treeList;
}

方法二

借助缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function buildLocationTree(locationList) {
let catchMap = new Map();
locationList.forEach(item => {
if(item.pid !== undefined) {
const id = catchMap.get(item.pid);
if(id) {
id.push(item)
} else {
catchMap.set(item.pid, [item])
}
}
})
locationList.forEach(item => {
const pid = catchMap.get(item.id);
if(pid) {
item.subLocations = pid;
}
})
return locationList.filter(item => item.pid === undefined);
}