JavaScript 中無需遞迴扁平化多層巢狀陣列的函式


問題陳述要求使用者,給定一個包含多個巢狀陣列的陣列,使用者需要將該陣列扁平化,並將任何超過一維的陣列轉換為 JavaScript 中的一維陣列,但主要條件是不使用遞迴。

它也是 JavaScript 中最常被問到的前端 JavaScript 問題之一,通常會給出一個深度巢狀的示例元素陣列,問題陳述要求將最深層的巢狀陣列扁平化為一個僅包含一維元素的集合。

什麼是 JavaScript 中的扁平化陣列?

扁平化陣列是在 JavaScript 中使用非遞迴函式將子陣列連線到單個元素陣列的新返回的一維陣列。它是降低陣列維度的過程。此外,扁平化陣列將原始陣列的維度降低到較低的數字,以便結果僅獲得一維陣列。

演算法

以下問題陳述透過一個特定的演算法解決,該演算法如下所示:

步驟 1 - 宣告一個名為 flatten 的函式,該函式將陣列元素作為輸入。

步驟 2 - 宣告並初始化結果陣列,該陣列將包含作為輸入給定的巢狀陣列結果的扁平化陣列。同時也用空陣列初始化結果陣列。

步驟 3 - 宣告一個棧資料結構,用於在沒有遞迴的情況下解決問題陳述,並用使用者給定的所有陣列元素初始化棧陣列。

步驟 4 - 宣告一個第一個元素變數來跟蹤相對於棧的 push 和 pop 操作的元素。

步驟 5 - 使用棧資料結構和 while 迴圈來檢查棧元素的長度是否大於 0 以執行某些任務。

步驟 6 - 將棧的第一個元素儲存在第一個元素變數中。

步驟 7 - 使用 if-else 語句來檢查第一個元素變數是簡單數字陣列還是巢狀陣列,使用 isArray 方法。

步驟 8 - 如果從棧中彈出的第一個元素是一個數組,我們使用 JavaScript 中的 splice 方法提取陣列中的元素,並使用 concat 方法將它們與儲存的第一個元素連線起來,其中 apply 函式也充當將一個函式繫結到另一個函式中的粘合劑。這是使用三個 JavaScript 方法並行地將巢狀陣列替換為其項並將其陣列維度降低到較低數字的最重要步驟。

步驟 9 - 如果特定的第一個元素不是陣列,則該數字將簡單地推入結果陣列中,並使用 splice 方法從原始陣列中永久刪除,以便使用相同的 while 迴圈和 if-else 條件再次向前移動並檢查其他元素。

步驟 10 - 一旦迴圈到達其終止條件,將返回新的結果陣列或您可以稱之為結果扁平化陣列,而無需使用遞迴。

示例

function flatten(arr) {

  var resultArray = [];

  var stackOfElements = arr;

  var firstElement;

  while (stackOfElements.length > 0) {

    firstElement = stackOfElements[0];

    if (Array.isArray(firstElement)) {

          Array.prototype.splice.apply(stackOfElements, [0, 1].concat(firstElement));
    } 
   
    else {
      resultArray.push(firstElement);

      stackOfElements.splice(0, 1);

    }

  }

  return resultArray;
}

const arr = [1, 4, 5, [
   5, 6, [
      6, 19, 5, [5]
   ], [5, 7, 6, [6, 8]], 8
], 6];


const out = flatten(arr);

console.log("output", out);

輸出

output [
   1, 4, 5, 5, 6, 6,
  19, 5, 5, 5, 7, 6,
   6, 8, 8, 6
]

時間和空間複雜度

以下問題陳述使用 JavaScript 方法(如 splice 和 concat 方法)解決,這些方法遍歷陣列元素,最壞情況下的時間複雜度為 O(n)。由於使用了棧資料結構將陣列的所有元素推入其中,因此問題陳述的空間複雜度為 O(n)。

結論

這就是我們如何在邏輯上以及在編碼上下文中解決上述問題陳述的方式,利用 JavaScript 方法(如 split 和 splice 方法)以及棧資料結構在其最有效的用例中。

更新於: 2023-08-21

522 次瀏覽

開啟您的 職業生涯

透過完成課程獲得認證

立即開始
廣告