Codewars 上隨機挑到的題目:Number of People in the Bus
【題目描述】
看測試用例比較好懂:
題目解釋:每一個
int[]
都有兩個正整數,第一個代表上車的乘客數,第二個代表下車的乘客數。最後的結果就是車子上還剩多少人。
Step 1: 新增測試用例,只有一個 station
【測試代碼】
【生產代碼】
Step 2: hard-code 回傳 p[0][0] - p[0][1]
【生產代碼】
先針對單一個 item hard-code 處理,等等只需要把 index = 0 的部分替換成 for loop 的 i 即可。
【重構測試代碼】擷取方法,將驗證行為封裝到 RemainPassengerShouldBe()
裡。
Step 3: 新增測試用例,有兩個 station 的情況
【測試代碼】
【生產代碼】hard-code,當還有第二個 station 時,累加 remainPassengerCount
。
Step 4: 新增測試用例,有三個 station 的情況
【測試代碼】重複了三次類似的處理,逼出生產代碼使用 loop。
【生產代碼】一樣先 hard-code,通過測試用例後,再重構出 for loop。
【重構】擷取方法,將 remainPassgerCount
的計算抽到 RemainPassengerCountOfCurrentStation()
中,避免同樣的計算重複三份。
【重構】以 for loop 取代 hard-code 的 [0]
, [1]
, [2]
index。
【通過 Codewars 上所有測試用例】
【重構】使用 LINQ 的 Aggregate()
來取代這個 for loop 的行為,讓語意更加清楚。
一行搞定這個 Aggregate 的行為!
結論
寫 LeetCode 久了,突然看到這樣的題目,一直在想是不是哪邊有陷阱。結果真的是一題單純到爆炸,單純考會不會寫程式的考題。
但我還是決定用 TDD 一路驅動跟重構出最後版本的代碼,希望可以提供給剛入門的朋友當參考。
GitHub commi history: Codewars_NumberOfPeopleInTheBus
大部分的 LINQ 都是在封裝 foreach loop 的巡覽行為,賦予其更簡單、有彈性、易讀的寫法,這種先寫出 loop 再重構成 LINQ,是學習 LINQ to object 本質很重要的一個脈絡。練久了,你就有火眼金睛,看到那些看似複雜的 foreach loop, 可以對照到是否可以重構成 LINQ 的 API 來表示。