Codog

关注微信公众号:Codog代码狗

0%

实现嵌套数组层次展开

一道高频面试题,方法有很多,基本思想都是递归。

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
// concat
function myFlat(arr, depth) {
if(depth <= 0 || !Array.isArray(arr)) {
return arr
}
let res = []
arr.forEach(item => {
res = res.concat(Array.isArray(item) ? myFlat(item, depth - 1) : item)
})
return res
}

// reduce
function myFlat2(arr, depth) {
if(depth <= 0 || !Array.isArray(arr)) {
return arr
}
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? myFlat2(cur, depth -1) : cur)
}, [])
}
Array.prototype.flat3 = function(depth) {
let res = this
while(depth > 0) {
res = [].concat(...res)
depth --
}
return res
}

function flat(arr) {
while (arr.some((i) => Array.isArray(i))) {
arr = [].concat(...arr);
}
return arr;
}

之所以可以数组的concat方法,是借助当它的参数为数组时,会将数组元素浅拷贝到新数组中:

示例:

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
38
39
40
41
42

// Example1
var alpha = ['a', 'b', 'c'];
var numeric = [1, 2, 3];
alpha.concat(numeric);
// result in ['a', 'b', 'c', 1, 2, 3]

// Example2
var num1 = [1, 2, 3],
num2 = [4, 5, 6],
num3 = [7, 8, 9];
var nums = num1.concat(num2, num3);
console.log(nums);
// results in [1, 2, 3, 4, 5, 6, 7, 8, 9]

// Example3
var alpha = ['a', 'b', 'c'];
var alphaNumeric = alpha.concat(1, [2, 3]);
console.log(alphaNumeric);
// results in ['a', 'b', 'c', 1, 2, 3]


// Example4
var num1 = [[1]];
var num2 = [2, [3]];
var num3=[5,[6]];

var nums = num1.concat(num2);

console.log(nums);
// results is [[1], 2, [3]]

var nums2=num1.concat(4,num3);

console.log(nums2)
// results is [[1], 4, 5,[6]]

// modify the first element of num1
num1[0].push(4);

console.log(nums);
// results is [[1, 4], 2, [3]]

还可以使用数组的toString()方法:

1
2
3
let sourceArr = [[0], [2, 3, 4], 1, [1, [2, 3]]];
// toString()结果为: "0,2,3,4,1,1,2,3"
sourceArr.toString().split(',').map(i => Number(i))

参考: https://juejin.im/post/5cefa11a518825334a39134c

ES2019提出了Array.flat()方法,参数为展开层级,传入Infinity可全部展开