在 JavaScript 中,將二維數組轉換為一維數組(扁平化)有多種方法,可根據數組結構復雜度、性能需求和兼容性選擇。以下是最常用的實現方式:
1. 使用 flat() 方法(ES2019+)
MDN釋義:flat() 方法會按照一個可指定的深度遞歸遍歷數組,并將所有元素與遍歷到的子數組中的元素合并為一個新數組返回。
語法:var newArray = arr.flat([depth]) depth 默認為 1
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
如果不知道數組是多少維度,可以傳 Infinity 來展開任意深度的嵌套數組
var arr = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
方法2:使用 reduce 與 concat
-
reduce
reduce() 方法對數組中的每個元素執行一個由您提供的reducer函數(升序執行),將其結果匯總為單個返回值。- 基本用法:
const total = [1, 2, 3].reduce((acc, cur) => acc + cur, 1); // 6
- 基本用法:
-
concat
concat() 方法用于合并兩個或多個數組。此方法不會更改現有數組,而是返回一個新數組。concat() 也適用于字符串。- 基本用法:
var arr = [1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5]
- 基本用法:
實例:
// 二維
const arr = [1, 2, [3, 4]];
arr.reduce((acc, cur) => acc.concat(cur), [])
// [1, 2, 3, 4]// 三維及以上可以使用遞歸
function flatArr(arr, dep = 1) {if (dep > 0) {return arr.reduce((acc, cur) =>acc.concat(Array.isArray(cur) ? flatArr(cur, dep - 1) : cur),[]);} else {return arr;}
}
flatArr([1, 2, [3, 4, [5, 6]]], 3);
// [1, 2, 3, 4, 5, 6]// 不知道數組維度,可以傳 Infinity
flatArr([1, 2, [3, 4, [5, 6]]], Infinity);
// [1, 2, 3, 4, 5, 6]
方法3:擴展運算符
// 二維
const arr = [1, 2, [3, 4]];
var newArr = [].concat(...arr);
// [1, 2, 3, 4]
方法4:使用forWach
forEach() 方法對數組的每個元素執行一次給定的函數。
基本用法:
arr.forEach(((item, index) => item))
實例:
// 二維及以上維度
const newArr = []; // 全局變量或者閉包也可以function flatArr(arr, dep = 1) {arr.forEach(ele => {if(Array.isArray(ele) && dep > 0) {flatArr(ele, dep - 1);} else {newArr.push(ele);}});return newArr;
}flatArr([1, 2, [3, 4, [5, 6]]], 3);
// [1, 2, 3, 4, 5, 6]```## 方法5:使用堆棧stack```bash
// 無遞歸數組扁平化,使用堆棧
// 注意:深度的控制比較低效,因為需要檢查每一個值的深度
// 也可能在 shift / unshift 上進行 w/o 反轉,但是末端的數組 OPs 更快
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
function flatten(input) {const stack = [...input];const res = [];while (stack.length) {// 使用 pop 從 stack 中取出并移除值const next = stack.pop();if (Array.isArray(next)) {// 使用 push 送回內層數組中的元素,不會改動原始輸入stack.push(...next);} else {res.push(next);}}// 反轉恢復原數組的順序return res.reverse();
}
flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
// 遞歸版本的反嵌套
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;
}
方法6:使用 Generator 函數
Generator 函數是 ES6 提供的一種異步編程解決方案,語法行為與傳統函數完全不同。
function* flatArr(array) {for (const item of array) {if (Array.isArray(item)) {yield* flatArr(item);} else {yield item;}}
}const arr = [1, 2, [3, 4, [5, 6]]];
const flattened = [...flatArr(arr)];
// [1, 2, 3, 4, 5, 6]