Try   HackMD

Array.flat()多維陣列轉一維陣列

Array.flat() 是 JavaScript 中的一個內建函數,用於將多維數組(陣列)轉換成一維數組。這個方法在處理多層嵌套數組時特別有用,它將嵌套的數組內的元素提取出來,並將它們放入一個新的一維數組中。這個函數可以接受一個整數參數,表示要扁平化的嵌套層級。

以下是 Array.prototype.flat() 的基本用法和一些示例:

基本用法:

const nestedArray = [1, [2, 3], [4, [5, 6]]];
const flatArray = nestedArray.flat();

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

在上面的示例中,nestedArray 包含了多層嵌套的數組,但 flat() 方法將它們轉換為一個一維數組 flatArray

指定扁平化的層級:

flat() 方法可以接受一個整數參數,用來指定要扁平化的嵌套層級。例如:

const deeplyNestedArray = [1, [2, [3, [4, [5]]]]];
const flatArray = deeplyNestedArray.flat(2);

console.log(flatArray); // [1, 2, 3, [4, [5]]]

在上面的示例中,我們通過將 2 傳遞給 flat() 方法,只扁平化了前兩層嵌套。

需要注意的是,如果你不指定參數,flat() 默認將扁平化所有的嵌套層級。

這是一個方便的方法,可以幫助你處理數組中的嵌套數據,使其更容易進行操作和處理。請注意,flat() 方法在ES6中引入,因此在較舊的JavaScript環境中可能不可用。

簡化原理

LeetCode 2625

Flatten Deeply Nested Array

多維數組是包含整數或其他多維數組的遞歸數據結構。
A multi-dimensional array is a recursive data structure
that contains integers or other multi-dimensional arrays.

展平數組是該數組的一個版本,刪除了部分或全部子數組並替換為該子數組中的實際元素。
A flattened array is a version of that array with some or all of the sub-arrays
removed and replaced with the actual elements in that sub-array.

僅當前嵌套深度小於“n”時才應執行此展平操作。
This flattening operation should only be done
if the current depth of nesting is less than n.

第一個數組中元素的深度被視為“0”。
The depth of the elements in the first array are considered to be 0.

請在不使用內置 Array.flat 方法的情況下解決它。
Please solve it without the built-in Array.flat method.

解決方案

  1. 先了解多維數組、遞迴、嵌套深度等定義

    ​​​let arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]]  ;  
    ​​​let n = 1;
    
    • 多維數組是包含整數或其他多維數組的遞歸數據結構。
      展平數組是該數組的一個版本,刪除了部分或全部子數組並替換為該子數組中的實際元素。
    • 僅噹噹前嵌套深度小於“n”時才應執行此展平操作。
      第一個數組中元素的深度被視為“0”。
    • 請在不使用內置 Array.flat 方法的情況下解決它。
  2. 宣告函式flat,接受一個多維數組arr和變數n用以設定展平深度

    ​​​var flat = function (arr, n) {
    ​​​   let answer = [];    
    
    ​​​   // 展平邏輯
    ​​​   
    ​​​   return answer;
    ​​​};
    
  3. 使用for迴圈遍歷多維陣列arr,判斷要進行遞迴還是元素放進answer陣列
    如果 n>0 且arr當前遍歷元素是陣列時進行遞迴
    如果 n≤0 就把當前遍歷元素放進answer陣列

    ​​​var flat = function (arr, n) {
    ​​​   let answer = [];
    ​​​   
    ​​​   // 展平邏輯
    ​​​   for(let i=0; i<arr.length; i++){        
    ​​​      if(n>0 && Array.isArray(arr[i])){        
    ​​​            //遞迴邏輯處理
    ​​​      }
    ​​​      else{ answer.push(arr[i]);}
    ​​​   }
    ​​​   
    ​​​   return answer;
    ​​​};
    
  4. 遞迴邏輯處理

    ​​​var flat = function (arr, n) {
    ​​​   let answer = [];
    ​​​   
    ​​​   // 展平邏輯
    ​​​   for(let i=0; i<arr.length; i++){        
    ​​​      if(n>0 && Array.isArray(arr[i])){     
    ​​​            //遞迴邏輯處理:
    ​​​            // ✓ 遞迴函式
    ​​​            // 目前處理的元素 arr[i] 作為參數傳遞給 flat 函數,同時將深度 n 減一。  
    ​​​            // ✓ 展開運算符...
    ​​​            // 將 flat(arr[i], n-1) 的結果展開為一系列的元素,
    ​​​            // 並將它們添加到 answer 陣列中。
    ​​​            answer.push(...flat(arr[i], n-1));
    ​​​      }
    ​​​      else{ answer.push(arr[i]);}
    ​​​   }
    ​​​   
    ​​​   return answer;
    ​​​};
    

遞迴解析1

let arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]]  ;  
let n = 1;

flat([4, 5, 6] , 1-1) 
flat([7, 8, [9, 10, 11], 12] , 1-1)
flat([13, 14, 15] , 1-1)

=> n=0 會進行else處理:把當前陣列元素都展開添加到 answer陣列中
=> output: [1,2,3,4,5,6,7,8,[9,10,11],12,13,14,15]

遞迴解析2

let arr = [[1, 2, 3], [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]] ;  
let n = 2;

flat([1, 2, 3] , 2-1) 
flat([4, 5, 6] , 2-1)
    => 當前陣列內沒有子陣列 會進行else處理:把當前陣列元素都展開添加到 answer陣列中

flat([7, 8, [9, 10, 11], 12] , 2-1)
    => 當前陣列內整數7,8,12以及子陣列[9,10,11] 
    => 7,8,12 會進行else處理:把當前陣列元素都展開添加到 answer陣列中
    => [9,10,11]判斷式成立進行遞迴
        => flat( [9, 10, 11] , 1-1)
        => n=0 會進行else處理:把當前陣列元素都展開添加到 answer陣列中

flat([13, 14, 15] , 2-1)
    => 當前陣列內沒有子陣列 會進行else處理:把當前陣列元素都展開添加到 answer陣列中
 
=> `...flat(arr[i], n-1)`展開遞迴處理結果 並將結果添加到 answer 陣列中。
=> output: [123456789101112131415]

相關練習

LeetCode 2695

Array Wrapper

創建一個類“ArrayWrapper”,在其構造函數中接受整數數組。 這個類應該有兩個特點:
Create a class ArrayWrapper that accepts an array of integers in its constructor. This class should have two features:

  • 當使用“+”運算符將此類的兩個實例相加時,結果值是兩個數組中所有元素的總和。
    When two instances of this class are added together with the + operator, the resulting value is the sum of all the elements in both arrays.

  • 當在實例上調用“String()”函數時,它將返回一個用括號括起來的逗號分隔字符串。 例如,“[1,2,3]”。
    When the String() function is called on the instance, it will return a comma separated string surrounded by brackets. For example, [1,2,3].

解決方案

  • valueOf()
    • 使用Array.flat(1); 將多維陣列平坦化為一維陣列
    • 使用Array.reduce(); 相加所有元素
  • toString()
    • 使用Array.join(,) 把所有的元素中間用,隔開並組合成字串
class ArrayWrapper {
    //this.nums=[[1,2],[3,4]]
    constructor(nums) {
      this.nums = nums;
    }

    valueOf() {
        const flattenArray = this.nums.flat(1);
        return flattenArray.reduce((sum, num) => sum + num, 0);
    }

    toString() {
      return `[${this.nums.join(',')}]`;
    }
}