告別 for 循環嵌套:JavaScript 數組迭代的函數式妙用
傳統的 for 循環往往在處理多層數組時,代碼變得冗長且難以維護。隨著函數式編程思想的普及,JavaScript 提供了一系列強大而優雅的數組方法,可以讓我們徹底告別嵌套循環的混亂,使代碼更加簡潔、可讀且易于維護。
一、嵌套循環的痛點
先看一個典型的嵌套 for 循環示例,假設我們需要從二維數組中篩選出所有偶數并將它們翻倍:
const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const result = [];
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] % 2 === 0) {
result.push(matrix[i][j] * 2);
}
}
}
console.log(result); // [4, 8, 12, 16]
這段代碼存在幾個問題:
- 代碼冗長,可讀性較差
- 使用中間變量存儲狀態
- 循環嵌套越多,代碼復雜度指數增長
- 調試困難,容易出錯
二、函數式方法的優雅替代
1. 扁平化嵌套數組:flat()
flat()方法可以將嵌套數組扁平化,這樣我們就可以對扁平化后的數組進行操作:
2. 映射與過濾:map()和filter()
結合map()和filter()方法,可以輕松實現篩選和轉換:
3. 一步到位:flatMap()
對于先扁平化再映射的常見操作,flatMap()提供了更高效的解決方案:
4. 深層嵌套數組處理
對于更深層次的嵌套,可以指定flat()的深度參數,或使用Infinity完全展開:
5. 遞歸與reduce()的強大組合
對于更復雜的嵌套結構處理,可以結合reduce()和遞歸實現靈活的解決方案:
functionprocessNestedArrays(arr, processFn) {
return arr.reduce((result, item) => {
if (Array.isArray(item)) {
return [...result, ...processNestedArrays(item, processFn)];
}
const processed = processFn(item);
return processed ? [...result, processed] : result;
}, []);
}
const nestedNumbers = [1, [2, 3], [4, [5, 6, [7, 8]]]];
const doubledEvens = processNestedArrays(
nestedNumbers,
num => num % 2 === 0 ? num * 2 : null
);
console.log(doubledEvens); // [4, 8, 12, 16]
盡管函數式方法在可讀性和維護性上有明顯優勢,但在極端性能要求的場景下,傳統循環可能略微高效。然而,現代 JavaScript 引擎對這些高階函數的優化已經相當出色,對于大多數應用場景,性能差異微乎其微,而代碼質量的提升則是顯著的。