# ... 展開運算符 `...` 展開運算符(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] ```