# Array.flat()多維陣列轉一維陣列 `Array.flat()` 是 JavaScript 中的一個內建函數,用於將多維數組(陣列)轉換成一維數組。這個方法在處理多層嵌套數組時特別有用,它將嵌套的數組內的元素提取出來,並將它們放入一個新的一維數組中。這個函數可以接受一個整數參數,表示要扁平化的嵌套層級。 以下是 `Array.prototype.flat()` 的基本用法和一些示例: ### 基本用法: ```javascript 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()` 方法可以接受一個整數參數,用來指定要扁平化的嵌套層級。例如: ```javascript 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. 先了解多維數組、遞迴、嵌套深度等定義 ```javascript 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`用以設定展平深度 ```javascript var flat = function (arr, n) { let answer = []; // 展平邏輯 return answer; }; ``` 3. 使用for迴圈遍歷多維陣列`arr`,判斷要進行遞迴還是元素放進`answer`陣列 如果 n>0 且`arr`當前遍歷元素是陣列時進行遞迴 如果 n≤0 就把當前遍歷元素放進`answer`陣列 ```javascript 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. 遞迴邏輯處理 ```javascript 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 ```javascript 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 ```javascript 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: [1、2、3、4、5、6、7、8、9、10、11、12、13、14、15] ``` ## 相關練習 ### 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(,) 把所有的元素中間用,隔開並組合成字串 ```javascript 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(',')}]`; } } ```