# 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(',')}]`;
}
}
```