笔试须知:

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

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

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

# 第一题

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

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

# 方法一

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
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 方法二

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

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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 第二题

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

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

# 方法一

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
14
15
16
17
18
19
20
21
22

# 方法二

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
1
2
3
4
5
6
7
8
9
10
11
12
13

# 第三题

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

function sum(){
  // coading...
}

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

1
2
3
4
5
6
7

# 方法一

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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13

# 第四题

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

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: "天河区" }
  ... 
]

1
2
3
4
5
6
7
8
9
10

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

var locationTree = buildLocationTree(locationList);

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

1
2
3
4
5
6

其中 locationTree 的结构应该如下:

{
    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
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 方法一

直接遍历

// 测试数据
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
20
21
22
23
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

# 方法二

借助缓存

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);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Last Updated: 2020-5-20 11:30:19