(前端)面試300問之(1)數(shù)組扁平化[6種方法]

一 問題

1 數(shù)組的扁平化盖喷?

1)就是將一個(gè)n層數(shù)組惩激、即n維數(shù)組(n>=1)轉(zhuǎn)換為只有一層的數(shù)組。

如數(shù)組 arr = [1, [2, [3, 4]]];

經(jīng)過我們 myFlatten 函數(shù)的處理后祟剔、

即調(diào)用 myFlatten(arr) 應(yīng)該得到 [1, 2, 3, 4] 于宙。

【注:以下內(nèi)容均假定 arr = [1, [2, [3, 4]]] 】扛稽。

二 解法一覽

1 解法一覽(思維導(dǎo)圖版)

2 解法一覽(文字版)

1)數(shù)組自帶的方法 —— flat
2)遞歸
3)結(jié)合 reduce函數(shù)
4)(toString && split) 或 (join && split)
5)擴(kuò)展運(yùn)算符 —— …
6)generator

三 具體解法與代碼

1 數(shù)組自帶的方法 —— flat

1)其可以傳入一個(gè)參數(shù)吁峻,表示要 展開的層數(shù) 。
arr.flat();
// 默認(rèn)展開1層在张,即與 arr.flat(1) 一樣用含,均得到 [1, [2, [3, 4]]]
arr.flat(Infinity);
// “無限層”展開,得到 [1, 2, 3, 4]

2 遞歸

1)這是大部分人比較常用的實(shí)現(xiàn)方法帮匾。
function myFlatten(arr) {
  // 先定義一個(gè) 保存結(jié)果的 數(shù)組
  var res_arr = [];
  // 對(duì)原先的數(shù)組進(jìn)行 map遍歷啄骇,
  // 根據(jù)當(dāng)前元素是數(shù)組還是“單個(gè)元素”去走向不同的分支
  arr.map(item => {
    if(Array.isArray(item)){
      // 當(dāng)前元素為數(shù)組,繼續(xù)調(diào)用 myFlatten 瘟斜,
      // myFlatten返回的是數(shù)組形式缸夹,所以需要使用 concat
      res_arr = res_arr.concat(myFlatten(item));
    }else{
      // 當(dāng)前元素為“單個(gè)元素”,直接 push 塞到結(jié)果數(shù)組
      res_arr.push(item);
     }
  });
  // 返回 “當(dāng)前處理的結(jié)果數(shù)組”
  return res_arr;
}

3 結(jié)合 reduce函數(shù)

1)遍歷數(shù)組每一項(xiàng)螺句,若值為數(shù)組則繼續(xù)遞歸遍歷虽惭,否則直接 concat 【這個(gè)和方案2的遞歸基本是類似的!】蛇尚。
function myFlatten(arr) {
    return arr.reduce((res_arr, cur_item) => {
        return res_arr.concat(
            // 核心:若為數(shù)組芽唇、繼續(xù)遍歷
            Array.isArray(cur_item)
            ? myFlatten(cur_item)
            : cur_item
        );
    }, []);
}

4 (toString && split) 或 (join && split)

2種方案
// 1)
// 調(diào)用數(shù)組的toString方法,將數(shù)組變?yōu)樽址?// 然后再用split分割還原為數(shù)組
function flatten(arr) {
  // 這里的 arr.toString() 會(huì)直接得到 '1,2,3,4' 這樣的字符串
  return arr.toString().split(',').map(function(item) {
    // return Number(item);
    return item;
  })
}

// 2)
// 和上面的toString一樣取劫,join也可以將數(shù)組轉(zhuǎn)換為字符串
function flatten(arr) {
  // arr.join(',) 得到的也是 '1,2,3,4' 這樣的字符串
  return arr.join(',').split(',').map(function(item) {
    // return parseInt(item);
    return item;
  })
}

5 擴(kuò)展運(yùn)算符

1)es6的擴(kuò)展運(yùn)算符能將二維數(shù)組變?yōu)橐痪S匆笤,如:[].concat(…[1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5]。利用這個(gè)特性谱邪,我們可以做一個(gè)遍歷炮捧,當(dāng) arr 中含有數(shù)組則使用一次擴(kuò)展運(yùn)算符,直到?jīng)]有為止惦银。
function flatten(arr) {
  // 核心:只要 arr數(shù)組中含有非一維的 子項(xiàng)寓盗,就繼續(xù) 擴(kuò)展!璧函!
  while(arr.some(item=>Array.isArray(item))) {
    arr = [].concat(...arr);
  }
  return arr;
}

6 generator

1)如下代碼
function* flatten(array) {
  for (const item of array) {
    if (Array.isArray(item)) {
      yield* flatten(item);
    } else {
      yield item;
    }
  }
}
[...flatten(arr)]; // [1, 2, 3, 4]

或者這么調(diào)用【因?yàn)?generator函數(shù)“會(huì)自動(dòng)實(shí)現(xiàn) Iterator傀蚌、遍歷接口”,
使得我們可以使用 for ... of ... 蘸吓,
別寫成了 for ... in ... 善炫。】
let res_arr = [];
for(const item of flatten(arr)) {
  res_arr.push(item);
}

四 總結(jié) & tips

1 雖然說寫了5種方法库继,但是核心也只有一個(gè):遍歷數(shù)組arr箩艺,若arr[i]為數(shù)組則遞歸遍歷窜醉,直至arr[i]不為數(shù)組然后與之前的結(jié)果concat。

2 各個(gè)方法之間的對(duì)比

1)整體的代碼調(diào)用:
整體的代碼調(diào)用.png
2)整體的執(zhí)行結(jié)果:
整體的執(zhí)行結(jié)果.png

3 總結(jié)

1)整體來說這6種的運(yùn)行結(jié)果都基本一樣艺谆,至于性能榨惰、可讀性來說,本文沒有做過多的嘗試,歡迎熱心的小伙伴去嘗試下并留言給 “三少”

4 tips

1)若面試中遇到這個(gè)題目了静汤,大家可以先假裝思索【該過程中順便把以上的6種方法在腦子過一遍】琅催,然后將自己記得比較深、較接近最優(yōu)解的 講 或 寫 給面試官即可虫给。若太快回答藤抡,會(huì)給面試官一種你背題等不好的印象,且太快回答肯能也會(huì)因?yàn)樽约罕磉_(dá)的不充分而失分哦~
2)二叉樹的主要遍歷方式無法就2種 —— 深度遍歷(DFS) 和 廣度遍歷(BFS)抹估,我們的學(xué)習(xí)方式也一樣缠黍,若我們對(duì)以上6種方法都有了解過【廣度】且 還能順暢地說、寫出里面的 2-3種方法【深度】药蜻,那么面試官會(huì)對(duì)我們刮目相看的(因?yàn)檫@程度基本可以秒掉其他大部分人了)瓷式。

五 更多

1)本人是20屆本科生,大廠语泽、創(chuàng)業(yè)公司都待過贸典,現(xiàn)在是BAT的1名前端工程師(目前正往“全棧”方向發(fā)展湿弦,已開始寫公司里的部分后端代碼~)瓤漏。
2)以下是個(gè)人整理的一些筆記和書籍(永久有效鏈接: https://pan.baidu.com/s/1SPc3umO6cZlBtoPylSaHzw 密碼: eqee ,若失效的話可以到vx公眾號(hào) “碼農(nóng)三少” 回復(fù) pdf 以進(jìn)行最新資料的獲燃瞻!):
個(gè)人技術(shù)筆記(350+算法題解蔬充、前端重點(diǎn)面經(jīng)匯總、圖解HTTP等).png
理財(cái)書籍pdf.png
技術(shù)書籍pdf.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末班利,一起剝皮案震驚了整個(gè)濱河市饥漫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罗标,老刑警劉巖庸队,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異闯割,居然都是意外死亡彻消,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門宙拉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宾尚,“玉大人,你說我怎么就攤上這事』吞” “怎么了御板?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長牛郑。 經(jīng)常有香客問我怠肋,道長,這世上最難降的妖魔是什么淹朋? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任笙各,我火速辦了婚禮,結(jié)果婚禮上瑞你,老公的妹妹穿的比我還像新娘酪惭。我一直安慰自己希痴,他們只是感情好者甲,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著砌创,像睡著了一般虏缸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嫩实,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天刽辙,我揣著相機(jī)與錄音,去河邊找鬼甲献。 笑死宰缤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晃洒。 我是一名探鬼主播慨灭,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼球及!你這毒婦竟也來了氧骤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤吃引,失蹤者是張志新(化名)和其女友劉穎筹陵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镊尺,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡朦佩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庐氮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片语稠。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旭愧,靈堂內(nèi)的尸體忽然破棺而出颅筋,到底是詐尸還是另有隱情宙暇,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布议泵,位于F島的核電站占贫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏先口。R本人自食惡果不足惜型奥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碉京。 院中可真熱鬧厢汹,春花似錦、人聲如沸谐宙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凡蜻。三九已至搭综,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間划栓,已是汗流浹背兑巾。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留忠荞,地道東北人蒋歌。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像委煤,于是被迫代替她去往敵國和親堂油。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容