JavaScript數(shù)組降維之將二維數(shù)組轉(zhuǎn)為一維數(shù)組的五種方案
在處理數(shù)據(jù)時,我們經(jīng)常會遇到這樣的結(jié)構(gòu):
const arr = [ [1, 2], [3, 4], [5, 6], ];
我們希望把它變成:
[1, 2, 3, 4, 5, 6];
這個過程被稱為 “數(shù)組扁平化” (Array Flattening)。
很多開發(fā)者知道 flat(),但你知道它有哪些替代方案嗎?在兼容性要求高的老項目中該怎么辦?如果數(shù)組層級不確定又該如何處理?
本文將帶你掌握 5 種 主流方法,從最簡單到最底層,徹底搞定數(shù)組降維。
1. 首選方案:Array.prototype.flat()
這是 ES2019 (ES10) 引入的最簡單、最直觀的方法。
基本用法
flat() 方法會創(chuàng)建一個新數(shù)組,其中所有子數(shù)組元素以遞歸方式連接到指定深度。
const arr = [ [1, 2], [3, 4], [5, 6], ]; // 默認只扁平化一層 const result = arr.flat(); console.log(result); // [1, 2, 3, 4, 5, 6]
控制深度
如果數(shù)組嵌套更深,可以傳入?yún)?shù)指定深度。
const deepArr = [1, [2, [3, [4]]]]; console.log(deepArr.flat()); // [1, 2, [3, [4]]] (默認深度 1) console.log(deepArr.flat(2)); // [1, 2, 3, [4]] (深度 2) console.log(deepArr.flat(Infinity)); // [1, 2, 3, 4] (無限深度,完全扁平)
優(yōu)點:
- 語法極簡,語義清晰。
- 支持自定義深度。
- 自動跳過空位(sparse arrays)。
注意:
- 兼容性:IE 不支持。如果需要支持 IE,請使用 Babel 轉(zhuǎn)譯或下面的其他方法。
2. 經(jīng)典方案:concat + spread
在 flat() 出現(xiàn)之前,這是最常用的“一行代碼”解法,適用于僅有一層嵌套的二維數(shù)組。
代碼實現(xiàn)
利用 Array.prototype.concat() 可以接受多個參數(shù)或數(shù)組作為參數(shù)的特性,結(jié)合展開運算符 ...。
const arr = [ [1, 2], [3, 4], [5, 6], ]; // 方法 A: 使用 apply (舊式寫法) const resultA = [].concat.apply([], arr); // 方法 B: 使用 Spread 運算符 (推薦,更現(xiàn)代) const resultB = [].concat(...arr); console.log(resultB); // [1, 2, 3, 4, 5, 6]
局限性
- 只能處理一層嵌套。如果數(shù)組是
[[1, [2]], [3]],結(jié)果會是[1, [2], 3],內(nèi)部的[2]不會被展開。 - 參數(shù)長度限制:如果數(shù)組非常大(例如超過幾萬個元素),
...arr可能會導致調(diào)用棧溢出(Maximum call stack size exceeded),因為concat的參數(shù)個數(shù)有限制。
3. 通用方案:reduce 累加器
reduce 是數(shù)組處理的神器,它可以靈活地構(gòu)建任何結(jié)構(gòu)。對于二維數(shù)組,我們可以用 reduce 配合 concat 來實現(xiàn)。
代碼實現(xiàn)
const arr = [
[1, 2],
[3, 4],
[5, 6],
];
const result = arr.reduce((acc, cur) => {
return acc.concat(cur);
}, []);
console.log(result); // [1, 2, 3, 4, 5, 6]
進階:配合 Spread
const result = arr.reduce((acc, cur) => [...acc, ...cur], []);
注意:[...acc, ...cur] 每次都會創(chuàng)建新數(shù)組,性能比 acc.concat(cur) 差,建議優(yōu)先使用 concat。
與 flat() 對比
reduce方案同樣默認只處理一層。- 優(yōu)點是兼容性極好(ES5 即可支持)。
- 缺點是代碼稍長,不如
flat()直觀。
4. 遞歸方案:處理任意深度嵌套
如果數(shù)據(jù)層級不確定(可能是三維、四維甚至更深),或者你需要兼容舊環(huán)境且不能使用 flat(Infinity),則需要使用遞歸。
代碼實現(xiàn)
function flattenDeep(arr) {
let result = [];
arr.forEach((item) => {
if (Array.isArray(item)) {
// 如果是數(shù)組,遞歸調(diào)用
result = result.concat(flattenDeep(item));
} else {
// 如果不是數(shù)組,直接加入
result.push(item);
}
});
return result;
}
// 測試
const deepArr = [1, [2, [3, [4, 5]]], 6];
console.log(flattenDeep(deepArr)); // [1, 2, 3, 4, 5, 6]
優(yōu)化版:使用 reduce + 遞歸
function flattenDeep(arr) {
return arr.reduce((acc, val) => {
return acc.concat(Array.isArray(val) ? flattenDeep(val) : val);
}, []);
}
優(yōu)點:
- 兼容所有環(huán)境。
- 邏輯清晰,易于理解。
注意:
- 遞歸過深可能導致棧溢出。對于極深層級的數(shù)據(jù),建議使用**棧(Stack)**實現(xiàn)的迭代方式。
5. 選型指南與性能對比
| 方法 | 適用場景 | 兼容性 | 性能 | 推薦指數(shù) |
|---|---|---|---|---|
flat() | 現(xiàn)代項目首選,代碼簡潔 | ES2019+ (需 Polyfill for IE) | ???? | ?????????? |
concat(...arr) | 確定只有一層嵌套,且數(shù)據(jù)量不大 | ES6+ | ??? | ?????? |
reduce + concat | 需要兼容舊瀏覽器,且只有一層嵌套 | ES5+ | ???? | ???????? |
| 遞歸/迭代 | 層級不確定,或需自定義過濾邏輯 | 所有環(huán)境 | ?? (遞歸有開銷) | ?????? |
最佳實踐建議
- 日常開發(fā):直接使用
arr.flat()。如果需要考慮 IE,引入core-js等 Polyfill 庫即可。 - 高性能要求:如果數(shù)組非常大(百萬級),避免使用
reduce配合展開運算符[...acc, ...item],因為它會頻繁創(chuàng)建新數(shù)組。推薦使用flat()或傳統(tǒng)的for循環(huán) +push。 - 復雜邏輯:如果在扁平化的同時需要過濾數(shù)據(jù)或轉(zhuǎn)換格式,
reduce是最靈活的選擇。
// 示例:扁平化并只保留偶數(shù) const arr = [ [1, 2], [3, 4], [5, 6], ]; const evenNumbers = arr.flat().filter((n) => n % 2 === 0); // [2, 4, 6]
總結(jié)
- 最簡單:
arr.flat() - 最兼容(單層):
[].concat(...arr) - 最靈活(多層/自定義):遞歸函數(shù)或
reduce
掌握這些方法,你就能從容應對任何數(shù)組嵌套場景。記住,工具沒有好壞,只有適不適合。在現(xiàn)代 Vue/React 項目中,請放心擁抱 flat()!
以上就是JavaScript數(shù)組降維之將二維數(shù)組轉(zhuǎn)為一維數(shù)組的五種方案的詳細內(nèi)容,更多關(guān)于JavaScript二維數(shù)組轉(zhuǎn)為一維數(shù)組的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序轉(zhuǎn)換uniapp的遷移步驟以及遇到的問題總結(jié)
最近公司有個需求,第一次遇到,把原生的微信小程序代碼轉(zhuǎn)換為uni-app項目,下面這篇文章主要給大家介紹了關(guān)于微信小程序轉(zhuǎn)換uniapp的遷移步驟以及遇到問題的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07
JavaScript實現(xiàn)向setTimeout執(zhí)行代碼傳遞參數(shù)的方法
這篇文章主要介紹了JavaScript實現(xiàn)向setTimeout執(zhí)行代碼傳遞參數(shù)的方法,分析了向setTimeout傳遞參數(shù)的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-04-04

