function _flat(targetArray, container = []) {if (!Array.isArray(targetArray)) return container;targetArray.forEach(item => {if (!Array.isArray(item)) {container.push(item);} else {_flat(item, container);}});return container;}const rst = _flat([[[[[[1],2],3],4],5,6],7]);console.log('rst: ', rst);方法二: Array.prototype.flat

近年来,ES6新增了Array.prototype.flat方法,旨在简化扁平化操作。
对付该方法,理解其事情事理意义重大。
它默认只会拆解一层嵌套数组
通过循环调用直到无法展开为止,我们可以得到完备扁平化的数组。

function _flat2(targetArray) {if (!Array.isArray(targetArray)) return [];let _loop = targetArray;while (true) {const beforeFlat = _loop.length;const _Arr = _loop.flat();const afterFlat = _Arr.length;if (beforeFlat === afterFlat) return _Arr;_loop = _Arr;}}const rst2 = _flat2([[[[[[1],2],3],4],5,6],7]);console.log('rst2: ', rst2);方法三: findIndex 和 splice

第三种方法利用了Array.prototype.findIndex以及Array.prototype.splice。
首先找到数组中第一个还未展开的数组元素,然后利用splice将其展开。
这种方法会变动原数组。

function _flat3(targetArray) {if (!Array.isArray(targetArray)) return [];while (true) {const arrItemIndex = targetArray.findIndex(item => Array.isArray(item));if (arrItemIndex === -1) return targetArray;targetArray.splice(arrItemIndex, 1, ...targetArray[arrItemIndex]);}}const rst3 = _flat3([[[[[[1],2],3],4],5,6],7]);console.log('rst3: ', rst3);方法四: stack

利用栈的数据构造可以仿佛过程中的遍历。
详细操作是:将源数组整体入栈,然后逐一出栈,检讨是否为数组。
若是数组则展开后连续入栈; 若不是则入另一个栈存储结果。
这种方法实质上与递归相同,但利用栈可以降落操作繁芜度。

html扁平化再探javascript数组扁平化技能 HTML

function _flat4(targetArray) {if (!Array.isArray(targetArray)) return [];const a = [...targetArray];const b = [];while (a.length) {const _tmp = a.pop();if (Array.isArray(_tmp)) {a.push(..._tmp);} else {b.push(_tmp);}}return b;}const rst4 = _flat4([[[[[[1],2],3],4],5,6],7]);console.log('rst4: ', rst4);方法五: toString 和 split

这种思路利用了数组的toString方法,该方法会将数组转换为由逗号分隔的字符串,然后利用split方法得到结果数组。

const arr = [1, [2, 3], 4, [[5]]];const rst = arr.toString().split(',').map(item => +item);

toString()方法的一个有趣特性是,它可以将多层嵌套的数组转换成一个由逗号分隔的扁平化字符串。
在字符串形态下,数组中各元素之间的嵌套构造信息丢失,仅保留了元素值。
例如,一个像[1, [2, [3, [4]]]]的数组,通过toString()方法处理后,就会变成"1,2,3,4"。
这正是我们期望的一维形态,只不过因此字符串的形式存在。

但这还不是完全的办理办法。
字符串虽然扁平化了,但数组还未形成。
这时split(',')方法派上了用场。
它根据逗号分隔符将字符串再次转换为数组,由于原始的嵌套构造已经被toString()方法抹除,结果数组便是一个完备扁平的数组。
末了,为了确保数组中的元素类型精确(由于split()会将每个元素当作字符串),可以利用map()方法将每个字符串元素转换成其原始类型。

const arr = [1, [2, 3], 4, [[5]]];const rst = arr.toString().split(',').map(item => +item);

在上面的代码中,+item是一个快速的技巧,用于将字符串转换为数字。

方法六: JSON.stringify

JSON.stringify和JSON.parse是一对强大的方法,可以用来序列化和解析数据。
在JavaScript中,这对方法常常被用来进行深拷贝操作,但它们同样可以用来进行数组的扁平化。

其核心思想是:首先利用JSON.stringify将多维数组转换为字符串形式,同时保持了数组元素之间的逗号分隔。
这时,嵌套数组被转换成了括号和逗号的组合。
接下来,通过正则表达式.replace(/$|$/g, "")移除字符串中所有的中括号[],剩下的就只有逗号以及数字。
末了,通过JSON.parse将处理后的字符串重新布局成JavaScript数组。

const arr = [1, [2, 3], 4, [[5]]];const res = JSON.stringify(arr).replace(/$|$/g, "");const _a = JSON.parse("[" + res + "]");

这种方法的妙处在于利用了JSON工具的序列化和解析能力,从而简化了扁平化操作。
须要把稳的是,由于JSON.stringify会将数组中的所有内容(包括数字、字符串、布尔值及null)序列化为字符串,以是在利用这种方法时,应担保数组内部不含有除上述类型之外的元素(比如函数或循环引用),由于这些无法通过JSON.stringify精确序列化。

在节制了这些方法后,便可以根据详细情形选择得当的扁平化方法。
每种方法都有实在用处景和性能考量。
节制这些技巧,你就可以更加自若地处理JavaScript中的数组扁平化问题。

原文链接:https://juejin.cn/post/7317553712192487464