JavaScript不使用flat實現(xiàn)數(shù)組扁平化的三種方法
你想在不使用數(shù)組的flat()方法的前提下實現(xiàn)數(shù)組扁平化,核心是通過遞歸或迭代的方式,逐層遍歷數(shù)組中的元素,把嵌套的子數(shù)組 “拆解” 成一維數(shù)組。我會給你幾種實用且易懂的實現(xiàn)方式,覆蓋不同場景需求。
方法 1:遞歸實現(xiàn)(最易理解,適合新手)
遞歸的核心思路是:遍歷數(shù)組的每一個元素,如果元素是數(shù)組,就繼續(xù)遞歸處理這個子數(shù)組;如果不是數(shù)組,就直接加入結(jié)果數(shù)組。
// 遞歸實現(xiàn)數(shù)組扁平化(可指定扁平化深度,默認(rèn)完全扁平化)
function flattenArray(arr, depth = Infinity) {
// 存儲最終扁平化結(jié)果
const result = [];
// 遍歷原數(shù)組的每一個元素
arr.forEach(item => {
// 判斷:如果當(dāng)前元素是數(shù)組,且還沒達(dá)到指定扁平化深度
if (Array.isArray(item) && depth > 0) {
// 遞歸處理子數(shù)組,深度減1
result.push(...flattenArray(item, depth - 1));
} else {
// 非數(shù)組元素直接加入結(jié)果
result.push(item);
}
});
return result;
}
// 測試用例
const nestedArr = [1, [2, [3, [4, 5]], 6], 7];
// 完全扁平化
console.log(flattenArray(nestedArr)); // [1, 2, 3, 4, 5, 6, 7]
// 只扁平化1層
console.log(flattenArray(nestedArr, 1)); // [1, 2, [3, [4, 5]], 6, 7]關(guān)鍵解釋:
Array.isArray(item):判斷元素是否為數(shù)組,這是扁平化的核心判斷條件;depth參數(shù):控制扁平化深度,和flat(depth)的參數(shù)邏輯一致,默認(rèn)Infinity表示完全扁平化;- 擴(kuò)展運(yùn)算符
...:把遞歸返回的子數(shù)組元素逐個推入結(jié)果數(shù)組,避免嵌套。
方法 2:迭代實現(xiàn)(循環(huán) + 棧,避免遞歸棧溢出)
如果數(shù)組嵌套層級極深(比如幾十層),遞歸可能會觸發(fā)棧溢出錯誤,這時用迭代(循環(huán))+ 棧的方式更穩(wěn)健。
// 迭代實現(xiàn)數(shù)組扁平化(完全扁平化)
function flattenArrayIterative(arr) {
// 用棧存儲待處理的元素,先把原數(shù)組淺拷貝入棧
const stack = [...arr];
const result = [];
// 只要棧不為空,就繼續(xù)處理
while (stack.length) {
// 彈出棧頂元素
const item = stack.pop();
if (Array.isArray(item)) {
// 如果是數(shù)組,把元素重新推入棧(注意順序:pop是從末尾取,所以要反向推入保持原順序)
stack.push(...item);
} else {
// 非數(shù)組元素加入結(jié)果
result.push(item);
}
}
// 因為pop是從后往前取,結(jié)果需要反轉(zhuǎn)恢復(fù)原順序
return result.reverse();
}
// 測試用例
const nestedArr = [1, [2, [3, 4], 5]];
console.log(flattenArrayIterative(nestedArr)); // [1, 2, 3, 4, 5]關(guān)鍵解釋:
- 棧(
stack)的特性是 “后進(jìn)先出”,所以最后需要reverse()恢復(fù)原數(shù)組順序; - 迭代方式?jīng)]有遞歸的棧深度限制,適合處理超深嵌套的數(shù)組。
方法 3:利用 reduce 簡化遞歸(簡潔寫法)
reduce 可以替代手動遍歷和結(jié)果數(shù)組的聲明,讓代碼更簡潔,核心邏輯和遞歸法一致。
// reduce實現(xiàn)扁平化
function flattenArrayReduce(arr, depth = Infinity) {
return arr.reduce((acc, item) => {
if (Array.isArray(item) && depth > 0) {
// 遞歸處理子數(shù)組,合并到累計結(jié)果中
return acc.concat(flattenArrayReduce(item, depth - 1));
} else {
// 非數(shù)組元素直接合并
return acc.concat(item);
}
}, []); // 初始值為空數(shù)組
}
// 測試用例
const nestedArr = [1, [2, [3]], 4];
console.log(flattenArrayReduce(nestedArr)); // [1, 2, 3, 4]關(guān)鍵解釋:
reduce的acc(累計值)就是最終的扁平化數(shù)組;concat方法可以把數(shù)組或單個元素合并到數(shù)組中,替代push(...)更簡潔。
總結(jié)
不用flat()實現(xiàn)數(shù)組扁平化的核心要點(diǎn):
- 核心邏輯:遍歷數(shù)組元素,判斷是否為數(shù)組,是則拆解層級,否則直接保留;
- 實現(xiàn)方式:
- 遞歸(
forEach/reduce):代碼易讀,適合常規(guī)嵌套深度的數(shù)組; - 迭代(棧):無棧溢出風(fēng)險,適合超深嵌套的數(shù)組;
- 遞歸(
- 擴(kuò)展點(diǎn):通過
depth參數(shù)可模擬flat(depth)的 “指定深度扁平化” 功能,適配不同需求。
這些方法都能兼容所有主流瀏覽器,且邏輯清晰,新手可以先從遞歸法入手理解,再根據(jù)實際場景選擇迭代法或 reduce 寫法。
以上就是JavaScript不使用flat實現(xiàn)數(shù)組扁平化的三種方法的詳細(xì)內(nèi)容,更多關(guān)于JavaScript不用flat數(shù)組扁平化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript同步Import,同步調(diào)用外部js的方法
javascript同步Import,同步調(diào)用外部js的實現(xiàn)代碼,測試確實可用2008-07-07
IE6中鏈接A的href為javascript協(xié)議時不在當(dāng)前頁面跳轉(zhuǎn)
IE6中當(dāng)鏈接A的href為javascript協(xié)議時不能在當(dāng)前頁面跳轉(zhuǎn),本例給出有效的解決方法,大家不妨參考下2014-06-06
js立即執(zhí)行函數(shù): (function ( ){})( ) 與 (function ( ){}( )) 有什么區(qū)別?
這篇文章主要介紹了js立即執(zhí)行函數(shù): (function ( ){})( ) 與 (function ( ){}( )) 有什么區(qū)別,需要的朋友可以參考下2015-11-11
Knockoutjs 學(xué)習(xí)系列(一)ko初體驗
本篇主要簡單介紹了knockoutjs中最重要的概念:可觀察對象(數(shù)組)。非常不錯具有參考借鑒價值,感興趣的朋友快來圍觀吧2016-06-06

