# [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(' ');
}
```
:::