题目描述: 已有多级嵌套数组 : [1, [2, [3, [4, 5]]], 6] 将其扁平化处理 输出: [1,2,3,4,5,6]
题目考查的内容就是数组扁平化,什么是扁平化呢?扁平化:就是将多维数组变成一维数组,不存在数组的嵌套
扁平化的方法:
ES6 flat
toString
正则替换
循环递归:循环+concat+push / 使用参数控制扁平化深度 / reduce / generator
使用栈结构
while循环+some
1.ES6 flat flat(depth)
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 🌟 参数:depth
(可选)指定要提取嵌套数组的结构深度,默认值为1 🌟 返回值:返回一个新数组,可展开任意深度的嵌套数组
1 let res = arr.flat (Infinity );
2.toString方法 1 2 3 function _flatten (arr ){ return arr.toString ().split (',' ).map (item =>parseFloat (item)); }
3.正则替换 看到嵌套数组,从字符串的角度上看就是多了很多的[
和]
,将它们替换就可以实现简单的扁平化
1 2 3 4 5 6 function _flatten (arr ){ let str = JSON .stringify (arr).replace (/(\[|\])/g ,'' ); str = '[' +str+']' ; arr = JSON .parse (str); return arr; }
4.循环递归 4.1 循环+concat+push 🌟思路:
循环判断数组的每一项是否是数组: Array.isArray(arr[i])
是数组就递归调用上面的扁平化一层的代码 result = result.concat(flatten(arr[i]));
不是数组,直接通过push
添加到返回值数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function _flatten (arr ) { let result = []; for (let i = 0 ; i < arr.length ; i++) { if (Array .isArray (arr[i])) { result = result.concat (flatten (arr[i])); } else { result.push (arr[i]) } } return result } function flatten (array ) { var flattend = []; (function flat (array ) { array.forEach (function (el ) { if (Array .isArray (el)) flat (el); else flattend.push (el); }); })(array); return flattend; }
4.2 使用参数控制扁平化深度 🌟:手写flat()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const _flat = (arr = [], depth = 1 ) => { const result = []; (function flat (arr, depth ) { arr.forEach ((item ) => { if (Array .isArray (item) && depth > 0 ) { flat (item, depth - 1 ) } else { result.push (item) } }) })(arr, depth) return result; }
4.3 巧用reduce reduce
方法为数组中的每个元素按序执行一个reducer函数,每一次运行 reducer 会将先前元素的计算结构作为参数传入,最后将其结果汇总为单个返回值。
1 2 3 4 5 6 7 8 9 10 const arr = [1 , [[2 , 3 ], 4 ],5 ]const flatten = (arr, deep = 1 ) => { if (deep <= 0 ) return arr; return arr.reduce ((res, curr ) => res.concat (Array .isArray (curr) ? flatten (curr, deep - 1 ) : curr), []) } console .log (arr, Infinity );
4.4 使用Generator函数 GeneratorFunction是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。它不同于普通函数,是可以暂停执行的,所以函数名之前要加星号,以示区别。整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用 yield 语句注明。Generator 函数的执行方法如下。 构造器生成新的生成器函数。
1 2 3 4 5 6 7 8 9 10 function * flatten (array ) { for (const item of array) { if (Array .isArray (item)) { yield * flatten (item); } else { yield item; } } }
5.使用栈结构 🪐 思路:
把数组通过一个栈来维护
当栈不为空的时候循环执行处理
pop()将栈尾出栈
如果出栈的元素是数组,就将该元素解构后每一元素进行入栈操作
出栈的元素不是数组就push进返回值res
反转恢复原数组的顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var arr1 = [1 ,2 ,3 ,[1 ,2 ,3 ,4 , [2 ,3 ,4 ]]];function flatten (arr ) { const stack = [...arr]; const res = []; while (stack.length ) { const next = stack.pop (); if (Array .isArray (next)) { stack.push (...next); } else { res.push (next); } } return res.reverse (); } flatten (arr1);
6.while循环+some方法 some :方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值。
🪐 思路: 通过some
来判断数组中是否用数组,通过while
不断循环执行判断, 如果是数组的话可以使用 拓展运算符...
每次只能展开最外层的数组,加上contact
来减少嵌套层数
1 2 3 4 5 6 7 8 9 function flatten (arr ) { while (arr.some (item => Array .isArray (item))) { console .log (...arr) arr = [].concat (...arr) console .log (arr) } return arr } console .log (flatten (arr));