<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
由於上半年參加了校招的技術面試, 前前後後面了20多個人了, 每次面試都會讓應聘者手寫一下陣列扁平化flat()
,但是發現居然沒有一個能夠完成寫出來, 所以打算總結一下如果遇到了陣列扁平化的題目(也可以叫做手動封裝flat()
方法),到底應該怎麼寫,怎麼寫可以得更高的分;
話不多說, 接下來我將站在面試官的角度分析所有常見的實現方法, 並附上對應的得分情況: 五星打分制
滿分: ⭐⭐⭐⭐⭐
題目描述:
已有多級巢狀陣列 : [1, [2, [3, [4, 5]]], 6]
將其扁平化處理 輸出: [1,2,3,4,5,6]
什麼是扁平化
定義 : 扁平化就是將多維陣列變成一維陣列,不存在陣列的巢狀
flat(depth) 方法會按照一個可指定的深度遞迴遍歷陣列,並將所有元素與遍歷到的子陣列中的元素合併為一個新陣列返回。
引數:
depth
(可選) 指定要提取巢狀陣列的結構深度,預設值為 1
返回值:
返回一個新陣列,包含陣列與提取巢狀陣列的所有元素的新陣列
使用 Infinity
,可展開任意深度的巢狀陣列
封裝思路: 使用 es6 自帶 API 處理
const arr = [1, [2, [3, [4, 5]]], 6] function flatten(params) { return params.flat(Infinity) } console.log(flatten(arr)); // 輸出: [1,2,3,4,5,6]
得分 : ⭐
直接使用自帶的方法可以很快的實現, 但是面試官當然不希望就看到這些呀 !
如果陣列的項全為數位,可以使用join(),toString()可以利用陣列toString() 轉為字串
function flatten(arr) { return arr.toString().split(',').map(item =>parseFloat(item)) } console.log(flatten(arr)); // 輸出:[ 1, 2, 3, 4, 5, 6 ]
得分 : ⭐ (並不是要考你的陣列的方法呼叫)
看到巢狀的陣列,如果在字串的角度上看就是多了很多[
和]
,如果把它們替換就可以實現簡單的扁平化
function flatten (arr) { console.log('JSON.stringify(arr)', typeof JSON.stringify(arr)) let str= JSON.stringify(arr).replace(/([|])/g, ''); str = '[' + str + ']'; arr = JSON.parse(str); return arr } console.log(flatten(arr))
得分 : ⭐ (並不是要考你的陣列的方法呼叫)
當只有一層巢狀陣列使用push的方式扁平化
[1, [2, 3,4,5,6]]
let result = []; for (let i = 0; i < arr2.length; i++) { result = result.concat((arr2[i])); } console.log(result); [ 1, 2, 3, 4, 5, 6 ]
如果有多層巢狀的陣列就需要使用 遞迴的思想 :
思路
function flatten(arr) { let result = []; for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { result = result.concat(flatten(arr[i])); } else { result.push(arr[i]) } } return result } console.log(flatten(arr));
或者使用forEach
立即執行函數
// 遞迴版本的反巢狀 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; }
當然迴圈可以更改成forEach迴圈,for of ...等其他迴圈,簡單的迴圈遞迴就能夠一樣的解決啦~
得分: ⭐⭐⭐ (能夠使用遞迴寫出陣列扁平化,缺少控制層級關係)
這個可以理解為手寫flat()
方法啦~
// forEach 遍歷陣列會自動跳過空元素 const eachFlat = (arr = [], depth = 1) => { const result = []; // 快取遞迴結果 // 開始遞迴 (function flat(arr, depth) { // forEach 會自動去除陣列空位 arr.forEach((item) => { // 控制遞迴深度 if (Array.isArray(item) && depth > 0) { // 遞迴陣列 flat(item, depth - 1) } else { // 快取元素 result.push(item) } }) })(arr, depth) // 返回遞迴結果 return result; } // for of 迴圈不能去除陣列空位,需要手動去除 const forFlat = (arr = [], depth = 1) => { const result = []; (function flat(arr, depth) { for (let item of arr) { if (Array.isArray(item) && depth > 0) { flat(item, depth - 1) } else { // 去除空元素,新增非 undefined 元素 item !== void 0 && result.push(item); } } })(arr, depth) return result; }
得分: ⭐⭐⭐⭐ (能夠使用遞迴寫出陣列扁平化,可以通過引數控制層級關係)
reduce 方法為陣列中的每個元素按序執行一個reducer
函數,每一次執行 reducer 會將先前元素的計算結構作為引數傳入,最後將其結果彙總為單個返回值
引數:
callbackFn
一個 reducer 函數,包含四個引數:callbackFn
時的返回值,在第一次呼叫時,若指定了初始值initialValue
,previousVal 的值就位 initialValue,否則初始值就是為陣列的索引為 0 的元素currentVal
:陣列中正在處理的元素,在第一次呼叫時,若指定了初始值,其值則為陣列索引為 0 的元素 array[0],否則為 array[1]initialValue
(可選) : 作為第一次呼叫 callback 函數時引數 previousValue 的值返回值: 使用 reducer 回撥函數遍歷整個陣列後的結果
思路:
當我們使用 reduce 來解析第一層陣列,可以得到:
const arr = [1, [[2, 3], 4],5] const result = arr.reduce((acc, val) => acc.concat(val), []); console.log(result); // 輸出: [1,[2,3],4,5]
可以看出上面的程式碼可以扁平化一層陣列,對於多層級巢狀的陣列, 這個時候就需要使用遞迴的思想來解決問題了,再次遍歷陣列,發現陣列元素任然是陣列的時候,再次執行上面扁平化
手寫方法
const arr = [1, [[2, 3], 4],5] function flatten (arr,deep=1) { return arr.reduce((acc,val) => acc.concat(Array.isArray(val)? flatten(val,deep-1):val),[]) } console.log(arr, Infinity); // 輸出:[ 1, 2, 3, 4, 5, 6 ]
得分: ⭐⭐⭐⭐ (能夠使用遞迴寫出陣列扁平化,巧用reduce方法可加分)
GeneratorFunction是協程在 ES6 的實現,最大特點就是可以交出函數的執行權(即暫停執行)。
它不同於普通函數,是可以暫停執行的,所以函數名之前要加星號,以示區別。
整個 Generator 函數就是一個封裝的非同步任務,或者說是非同步任務的容器。非同步操作需要暫停的地方,都用 yield 語句註明。Generator 函數的執行方法如下。
構造器生成新的生成器函數
function* flatten(array) { for (const item of array) { if (Array.isArray(item)) { yield* flatten(item); } else { yield item; } } }
得分: ⭐⭐⭐ (使用Generator 函數 進行遞迴)
遞迴迴圈都可通過維護一個堆結構來解決
如果不使用遞迴陣列來實現扁平化,可以使用堆疊來解決
深度的控制比較低效,因為需要檢查每一個值的深度
思路:
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]]; function flatten(arr) { const stack = [...arr]; 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]
得分: ⭐⭐⭐⭐ (使用資料結構棧的特性取代遞迴操作,減少時間複雜度)
some :方法測試陣列中是不是至少有 1 個元素通過了被提供的函數測試。它返回的是一個 Boolean 型別的值。
思路
通過some來判斷陣列中是否用陣列,通過while不斷迴圈執行判斷, 如果是陣列的話可以使用 拓展運運算元... ... 每次只能展開最外層的陣列,加上contact
來減少巢狀層數,
function flatten(arr) { while (arr.some(item=> Array.isArray(item))) { console.log(...arr) arr = [].concat(...arr) console.log(arr) } return arr } console.log(flatten(arr));
得分: ⭐⭐⭐⭐ (使用while迴圈取消遞迴操作, 巧用some操作進行判斷)
以上就是JS前端面試陣列扁平化手寫flat函數範例的詳細內容,更多關於JS陣列扁平化flat函數的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45