# [Codewars] Your order, please - 陣列中的 elements 依照自身的數字編排成新的字串 ###### tags: `解題筆記` ## 練習資訊: 等級:6 kyu 題目:[Your order, please](https://www.codewars.com/kata/55c45be3b2079eccff00010f) 練習時間:2022/10/10 ## 題目說明: 函式會接收字串,每一個單字內都會有一個數字,而該數字就是該單字的正確順序(起始為 1)。 Your task is to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result. Note: Numbers can be from 1 to 9. So 1 will be the first word (not 0). If the input string is empty, return an empty string. The words in the input String will only contain valid consecutive numbers. ```javascript= "is2 Thi1s T4est 3a" --> "Thi1s is2 3a T4est" "4of Fo1r pe6ople g3ood th5e the2" --> "Fo1r the2 g3ood 4of th5e pe6ople" "" --> "" ``` ### 我的方法 1. 因為要抓每一個單字,所以先用 `Array.split(' ')'` 以空白為切分的單位得到陣列(且每一個 element 都是一個單字) 2. 再用 `Array.sort()` 排序 - `Array.sort()` 會跑完陣列中每一個 element,如果該次迴圈回傳 > 0,那麼 `Array.sort((a, b))` 中的 `a` 就會被排在前面 3. 因為必須要以字串內的數字為編排順序,所以使用正則表達式抓出 element 中的數字,以便 `Array.sort()` 在每一次迴圈中比對 4. 最後再用 `Array.join(' ')` 以空白當作 element 之間的間隔,將陣列組回字串 ```javascript= function order(words){ return words === '' ? words : words.split(' ').sort((first, second) => { const firstNum = getNumFromStr(first); const secondNum = getNumFromStr(second); return firstNum - secondNum; }).join(' '); } function getNumFromStr(string) { return +string.match(/\d+/)[0] } ``` ### 厲害的解答 1. 為了順利讀取字串中每個單字,一樣先轉成陣列 `Array.split(' ')` -> 將字串中空格的部分當作區隔組成新的陣列 2. 開一個 reference 存放整理好的陣列資料 3. 因為每個 elements 內有的數字是隨機編排的,因此不可能只跑單次迴圈比對所有的單字(這樣子只會比對目前與上一個的關係),所以勢必要跑兩次 > 即便跑兩次,知道裡面會先跑完才會跑外面的,要怎麼正確地排序? > - 已經知道題目保證會給依照順序的數字(所以用 index 判別是非常適合) > - 巢狀迴圈回先跑完裡面才會跑外面,所以就可以用外層的迴圈的計數當作基準,由內層迴圈負責讀取每個單字,找出符合當前基準(也就是外層迴圈的計數)之單字 #### 為什麼外層迴圈需要走完全部的 length,即便最後一次外層會拿到 `undefined`,也需要走內層的迴圈? 因為題目給的起始數字是 1,不是 0,所以必須要走完陣列全部的 `length`,要不然會無法讀取到最後一個單字。對於內層迴圈則是無影響,反正對內層重要的是拿到正確的計數比對。 :::spoiler ```javascript= function order(words){ var array = words.split(' '); var sortedArray = []; // WHY? for(i = 0; i <= array.length; i++) { for(j = 0; j < array.length; j++) { if(array[j].indexOf(i) >= 0) { sortedArray.push(array[j]); } } } return sortedArray.join(' '); } ``` :::