# ... 展開運算符
`...` 展開運算符(Spread Operator)是 JavaScript 中的一個特性,它允許你將一個陣列或物件拆分成獨立的元素或鍵值對。展開運算符可以應用在多種情況下,使得代碼更加簡潔且易於理解。
以下是 `...` 展開運算符的一些常見用法:
1. 展開陣列(Spread Array):
你可以使用展開運算符來將一個陣列中的元素展開成獨立的值,例如:
```javascript
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];
console.log(arr2); // [1, 2, 3, 4, 5, 6]
```
2. 合併陣列:
展開運算符還可用於合併多個陣列,例如:
```javascript
const arr1 = [1, 2];
const arr2 = [3, 4];
const combinedArray = [...arr1, ...arr2];
console.log(combinedArray); // [1, 2, 3, 4]
```
3. 陣列複製:
使用展開運算符可以複製一個陣列,而不會影響原始陣列,例如:
```javascript
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];
console.log(copiedArray); // [1, 2, 3]
```
4. 創建函數參數列表:
在函數調用時,你可以使用展開運算符來將一個陣列中的元素傳遞給函數作為參數,例如:
```javascript
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
const result = sum(...numbers);
console.log(result); // 6
```
5. 物件展開(Spread Object):
除了陣列,展開運算符還可以用於物件,用來合併或複製物件的屬性,例如:
```javascript
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, ...obj1 };
console.log(obj2); // { a: 1, b: 2, c: 3 }
```
展開運算符是一個功能強大且方便的 JavaScript 特性,可以簡化許多操作,提高代碼的可讀性和可維護性。它在 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]
```