欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS實現(xiàn)數(shù)組扁平化的方法總結(jié)

 更新時間:2024年02月29日 08:41:53   作者:minxcs  
數(shù)組扁平化相信不少朋友在一些面試中被問到過,這在我們?nèi)粘>幊讨幸彩且粋€常規(guī)操作,它需要我們將一個多維數(shù)組轉(zhuǎn)化成一個一維數(shù)組,所以,借著這篇文章,我們今天就一起來匯總一下幾種數(shù)組扁平化的方式,需要的朋友可以參考下

嘮一嘮

數(shù)組扁平化相信不少朋喲在一些面試中被問到過,這在我們?nèi)粘>幊讨幸彩且粋€常規(guī)操作,它需要我們將一個多維數(shù)組轉(zhuǎn)化成一個一維數(shù)組。當(dāng)然,我相信很多朋友都能回答上這個問題,但如果面試官要我們多回答幾種,可能有些朋友就答不上來了,所以,借著這篇文章,我們今天就一起來匯總一下幾種數(shù)組扁平化的方式。

1. 普通遞歸方法

  • 相信掘友們首先能想到的實現(xiàn)數(shù)組扁平化解法是使用遞歸函數(shù)。該方法通過遍歷數(shù)組中的每個元素,檢查它是否還是一個數(shù)組。如果是,則對子數(shù)組進(jìn)行同樣的扁平化操作,并將結(jié)果合并到最終的一維數(shù)組中。例如:
let arr = [1,2,[3,4,[5,6]]]

function flattenArray(arr) {
  let result = []
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(flattenArray(arr[i]));
    } else {
      result.push(arr[i])
    }
  }
  return result
}

console.log(flattenArray(arr));  // [ 1, 2, 3, 4, 5, 6 ]

2. reduce() 方法

  • 利用Array.prototype.reduce()函數(shù)的累加器特性,遍歷數(shù)組并將子數(shù)組扁平化后的結(jié)果合并到最終的一維數(shù)組中。其實也是遞歸,不過不像上面一樣用for循環(huán),和上面代碼差別不大,這里主要是利用了reduce方法,代碼書寫起來更簡潔。
let arr = [1,2,[3,4,[5,6,[7,8]]]]

function flattenWithReduce(arr) {
  return arr.reduce((acc, val) => 
    acc.concat(Array.isArray(val) ? flattenWithReduce(val) : [val]),
    []
  );
}

console.log(flattenWithReduce(arr)) // [1, 2, 3, 4, 5, 6, 7, 8]

優(yōu)點:可讀性強,邏輯清晰,無需額外創(chuàng)建函數(shù)閉包。 缺點:對于非常深的嵌套結(jié)構(gòu),性能可能不如使用flat()方法。

3. Array.prototype.flat()

  • ES6引入了flat()方法,可以直接對數(shù)組進(jìn)行扁平化操作,可以指定扁平化的層級深度。
let arr = [1,2,[3,4,[5,6,[7,8,[9]]]]]

function flattenWithFlat(arr) {
  return arr.flat(Infinity) // Infinity表示完全扁平化所有層級
}

console.log(flattenWithFlat(arr)) // [1,2,3,4,5,6,7,8,9]

優(yōu)點:簡潔高效,原生支持,適合現(xiàn)代瀏覽器環(huán)境。 缺點:舊版瀏覽器不支持此方法,需要polyfill或其他兼容方案。

4. 擴展運算符與concat

  • 利用擴展運算符(...)和concat()結(jié)合,逐步展開嵌套數(shù)組。
let arr = [1,2,[3,[4],[5,6,[7,8,[9]]]]]

function flattenWithSpread(arr) {
  while (arr.some(item => Array.isArray(item))) {
    arr = [].concat(...arr)
  }
  return arr
}

console.log(flattenWithSpread(arr)); // [1,2,3,4,5,6,7,8,9]

優(yōu)點:代碼相對簡潔,易于理解。 缺點:循環(huán)執(zhí)行次數(shù)取決于數(shù)組嵌套深度,效率相對較低。

5. 廣度優(yōu)先搜索與隊列

  • 該方法采用廣度優(yōu)先搜索,也就是我們常說的BFS策略來扁平化嵌套數(shù)組。首先創(chuàng)建一個隊列并將原數(shù)組作為初始節(jié)點入隊。然后進(jìn)入循環(huán)階段,只要隊列不為空,就從隊列頭部取出一層元素(即當(dāng)前層級的所有子數(shù)組或值),并檢查每個元素是否為數(shù)組。如果是數(shù)組,則將其元素逐個加入隊列后部;如果不是數(shù)組,則直接將值加入結(jié)果數(shù)組中。循環(huán)直至隊列為空,此時結(jié)果數(shù)組中包含了所有已展開的一維元素。
let arr = [1,2,[3,[4],[5,6,[7,8,[9]]]]]

function flattenWithBFS(arr) {
  const queue = [arr] // 創(chuàng)建隊列,初始化為待處理的數(shù)組
  const result = [] 

  while (queue.length > 0) { 
    const levelItems = queue.shift() // 取出隊列首部的一層元素
    for (const item of levelItems) { // 遍歷當(dāng)前層級的每個元素
      if (Array.isArray(item)) { 
        queue.push(item); 
      } else {
        result.push(item) 
      }
    }
  }

  return result 
}

console.log(flattenWithBFS(arr)) // [1,2,3,4,5,6,7,8,9]

優(yōu)點:

  • 空間效率較高:通過使用隊列結(jié)構(gòu)進(jìn)行層次遍歷,能夠保證在有限的循環(huán)次數(shù)內(nèi)完成對任何深度嵌套數(shù)組的扁平化。
  • 無需遞歸調(diào)用棧:相比于遞歸方法,這種方法避免了因深層嵌套導(dǎo)致的棧溢出問題。

缺點:

  • 時間復(fù)雜度:盡管比擴展運算符結(jié)合concat()的方法有所改進(jìn),但在極端情況下(例如,非常深且寬的樹形結(jié)構(gòu)),仍需多次迭代才能完全扁平化數(shù)組。
  • 代碼相對復(fù)雜:相較于簡單的擴展運算符與concat()結(jié)合的方式,此方法涉及隊列操作,理解起來可能需要更多時間。

6. 深度優(yōu)先搜索與堆棧

  • 該方法利用了堆棧數(shù)據(jù)結(jié)構(gòu)進(jìn)行深度優(yōu)先搜索,也就是DFS。首先將待處理的原數(shù)組轉(zhuǎn)換為堆棧,并創(chuàng)建一個空的結(jié)果數(shù)組用于存儲扁平化后的一維元素。在循環(huán)中,只要堆棧不為空,就從堆棧頂部取出當(dāng)前元素。如果該元素是數(shù)組,則將其所有元素壓入堆棧;如果不是數(shù)組,則直接將其添加到結(jié)果數(shù)組的開頭。這個過程會不斷深入到嵌套數(shù)組的最底層,然后再逐層返回,直至堆棧為空。
let arr = [1,2,[3,[4],[5,6,[7,8,[9]]]]]

function flattenWithDFS(arr) {
  const stack = [...arr] // 將原數(shù)組轉(zhuǎn)換為堆棧
  const result = [] 

  while (stack.length > 0) { // 當(dāng)堆棧中有待處理元素時
    const current = stack.pop() // 取出堆棧頂部的元素

    if (Array.isArray(current)) { 
      stack.push(...current) // 將其所有元素壓入堆棧
    } else {
      result.unshift(current) // 否則將非數(shù)組元素添加到結(jié)果數(shù)組的開頭
    }
  }

  return result 
}

console.log(flattenWithDFS(arr));  // [1,2,3,4,5,6,7,8,9]

優(yōu)點:

  • 遞歸思想簡化實現(xiàn):深度優(yōu)先搜索天然適用于解決遞歸問題,此方法避免了顯式遞歸調(diào)用,但仍保持了遞歸處理的思想。
  • 無需額外空間復(fù)雜度:相比于廣度優(yōu)先搜索需要隊列保存每一層級的數(shù)據(jù),深度優(yōu)先搜索僅需一個堆棧即可,對于內(nèi)存資源有限的情況更為友好。

缺點:

  • 遍歷順序:深度優(yōu)先搜索可能導(dǎo)致元素在扁平化后的一維數(shù)組中的順序與原始嵌套數(shù)組中的層級順序不同。
  • 棧溢出風(fēng)險:當(dāng)面對極深的嵌套數(shù)組時,由于使用堆棧進(jìn)行遞歸模擬,可能會遇到JavaScript堆棧大小限制導(dǎo)致的棧溢出錯誤。

7. lodash庫的_.flattenDeep()

  • lodash庫提供了一個現(xiàn)成的方法_.flattenDeep(),可以處理任意深度的嵌套數(shù)組。
import _ from 'lodash'

let arr = [1,2,[3,[4],[5,6,[7,8,[9]]]]] 

const flattenedArr = _.flattenDeep(nestedArr)

console.log(flattenedArr)

優(yōu)點:第三方庫封裝,功能強大且經(jīng)過優(yōu)化,適用于各種復(fù)雜場景。 缺點:增加項目依賴,不適合僅需簡單扁平化且關(guān)注性能與體積的應(yīng)用場景。

以上就是七種常見的數(shù)組扁平化的方式了,掌握了這七種數(shù)組扁平化的方法,這類問題相信你回答起來也會得心應(yīng)手。今天就聊到這,至于數(shù)組扁平化的應(yīng)用場景本文并未介紹,當(dāng)然這也是一個非常重要的知識點,不過本文主要是總結(jié)一些方法,對于應(yīng)用場景感興趣的掘友們可自行搜索哦。如果還有其他的數(shù)組扁平化方法,歡迎大佬在評論區(qū)補充哦。

到此這篇關(guān)于JS實現(xiàn)數(shù)組扁平化的方法總結(jié)的文章就介紹到這了,更多相關(guān)JS數(shù)組扁平化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論