# [Codewars] Adding values of arrays in a shifted way - 既有的 element 相加,多的直接推進去 ###### tags: `解題筆記` ## 練習資訊 等級:7 kyu 題目:[Adding values of arrays in a shifted way](https://www.codewars.com/kata/57c7231c484cf9e6ac000090) 練習時間:2023/03/04 ## 題目說明 函式接受兩個 parameters,第一位為陣列,其值也是陣列,且每一個陣列長度都相同,陣列的值也確保是數字。第二位是數字,代表推移的位置。此函式最後需要回傳一個陣列,值為數字,為第一位 parameter 配合第二位 parameter 移動的結果。 #Adding values of arrays in a shifted way You have to write a method, that gets two parameter: 1. An array of arrays with int-numbers 2. The shifting value #The method should add the values of the arrays to one new array. The arrays in the array will all have the same size and this size will always be greater than 0. The shifting value is always a value from 0 up to the size of the arrays. There are always arrays in the array, so you do not need to check for null or empty. #1. Example: ```javascript= [[1,2,3,4,5,6], [7,7,7,7,7,-7]], 0 1,2,3,4,5,6 7,7,7,7,7,-7 --> [8,9,10,11,12,-1] ``` #2. Example ```javascript= [[1,2,3,4,5,6], [7,7,7,7,7,7]], 3 1,2,3,4,5,6 7,7,7,7,7,7 --> [1,2,3,11,12,13,7,7,7] ``` #3. Example ```javascript= [[1,2,3,4,5,6], [7,7,7,-7,7,7], [1,1,1,1,1,1]], 3 1,2,3,4,5,6 7,7,7,-7,7,7 1,1,1,1,1,1 --> [1,2,3,11,12,13,-6,8,8,1,1,1] ``` Have fun coding it and please don't forget to vote and rank this kata! :-) I have created other katas. Have a look if you like coding and challenges. ## 我的方法 ==該次迭代才處理變更起點== - 讀取第一位的陣列 - 建立一個 `result`,並給初始值 `[]` - 處理 `result` - 先灌第一筆陣列的資料當作基底(因為題目會確保每一組陣列的 `length` 都是一樣的) - 第二組開始就會依照 `shift` 決定操作的起點 - `shift` 代表跳過多少位置後才開始,因為 `index` 是以 `0` 為起點,且 `shift` 是代表跳過多少之後,所以直接拿 `shift` 操作起點 - 有 1 + 組陣列,起點的變化就是 `n * shift` ```javascript! shift (2) 1 , 1 , 1 1, 1, 1 (2 * 1) 1, 1, 1 (2 * 2) ``` - 但也是要拿每一組陣列的 `index`,當作更新跳過的位置,並檢查該位置是否有值 - 有值就相加,沒值代表是該陣列經 `shift` 更動後必須塞入 `result` 的值 ```javascript= function addingShifted (arrayOfArrays, shift) { const result = []; // 讀取 arrayOfArrays 中的 element -> [] for (let i = 0; i < arrayOfArrays.length; i ++) { // 第一個 [] 就直接塞入 result 當作基底 if (i === 0) { for (const arr of arrayOfArrays[i]) { result.push(arr) } } else { // 讀取第二組(之後) [] 的 element for (let j = 0; j < arrayOfArrays[i].length; j ++) { // 實際該組 [] 經過 shift 更動後的起始點 // 為什麼要 * i? // 因為 i 代表這組陣列是第幾個,其起始點就是 shift * i const nextIndex = shift * i > 0 ? shift * i : null if (nextIndex === null) { result[j] = result[j] + arrayOfArrays[i][j] } else { // 如果 result 內 需要相加的 index 沒值,就必須推,代表是該組陣列是已經過 shift 的移動 if (result[nextIndex + j] !== undefined) { result[nextIndex + j] = result[nextIndex + j] + arrayOfArrays[i][j] } else { result.push(arrayOfArrays[i][j]) } } } } } return result } ``` ## 厲害的解答 ==上組陣列結束前就先處理下一組== - 一樣是建立一個 `result` 用來塞值,以便計算 - 建立該組 array 所屬的變更起點(因為 `shift` 代表是在 `x` 之後計算,因此直接拿來當 `index`) - 第一次迭代也是直接塞值,第二次開始就會先加既有的或者推入 - `||` 左邊是 `false` 就回傳右邊的,左邊為 `true` 就回傳左邊的 - 因為 `index` 在陣列內找不到就會回傳 falsy value `undefined`,因此可以用 `||` 判斷是與既有的值相加還是用 `0` - 讀取陣列的值也要靠 `index`,判斷該組次陣列的值是否有對應到值 - 每一次迭代 array 的組次後都會更新下一組陣列的變更起點(重複加 `shift`) ```javascript! shift (2) // 第 0 次 結束後更新變更起點 1 , 1 , 1 // 第 1 次,因為上一次結束前後變更,所以這次的開頭就會到 index 2,結束前又變更起點 1, 1, 1 (2) // 第 2 次 ... 1, 1, 1 (4) ``` :::spoiler ```javascript= function addingShifted (arrayOfArrays, shift) { const result = []; let startIndex = 0; // 讀取陣列 for (const arr of arrayOfArrays) { // 讀取陣列的 element for (let i = 0; i < arr.length; i += 1) { // 透過 index 檢查是否有對應到值 // index 更新值 與 0 + arr[i] 十分聰明地表達是要相加還是不用 result[startIndex + i] = (result[startIndex + i] || 0) + arr[i] } startIndex += shift } return result } ``` :::