最近,因為公司需要重構一個項目,我們同事遇到一個需求,本來這部分事情是后端做的現在放到前端來,這個需求是這樣的,項目中經常能遇到關于城市列表的數據,此數據像這個樣子
這是原始數據,需要我們前端進行按首字母來分組,變成下面的樣子
這對于我們來說也許不難,但是得到相同的結果,采取的方式不同代碼量,和可維護性不盡相同,可能每個人解決的方式不一樣。下面說一下我同事是怎么實現現的。
因為本人比較喜歡函數式編程,喜歡把具體的細節封裝在函數里,所以平時也會喜歡使用數組比較“函數式的api”, 我會這樣解決上面的問題
這段代碼同樣可以獲取到字母集合。接下來就是比較關鍵的一步了,同事采取的方法是遍歷字母數組,以及城市數組,匹配城市的字母和數組里面的字母是否相等,如果相等,就在此字母對應的數組里面push此城市,且看代碼
結果是正確的,按照字母進行分組了
但其實這樣會不會太繁瑣了,首先傳統的for循環可是使用foreach來代替,其次如果不是雙層遍歷,對于字母的判斷是沒有必要的,其實我們可以使用obj[key]這種形式,其實這是一種hash表,這樣做我們可以同時完成字母的去重,以及城市的分類,且看代碼
上面代碼可以一次性完成分組,可能有的人會說這樣代碼的可讀性不好,其實如果使用這種高封裝的api熟練的時候,一樣就看出這段代碼的意思,同時有很多情況下,我們只關心輸入和輸出的情況下,這種代碼帶來的好處顯而易見,因為我們并不關心你實現的細節,這有點函數式,函數式編程也是只關心輸入輸出,對于實現細節是隱藏的,如果想知道具體實現,就看源碼。
當然上面的代碼依然不是很通用,比如下次我們不想依據letter這個字段分組,我們可能要重寫一遍代碼,然而對比代碼,可能只有細微的差別,這個時候我們可以再進行封裝,實現一個lodash庫里面的groupBy,代碼如下
當我們是在項目中引入這個庫的時候,我們可能只關心,傳入的列表數據,以及得到的已經分組過的數據是不是我們想要的,而并不關心庫內部是如何實現分組的,并且我們可以定制我們的分組規則,而不耦合具體的某個字段,這樣的好處顯而易見看下執行結果
可以看到上面的方法很靈活也很通用,當然這有點“函數式”。這樣的結果其實我們完成分組只用了一行代碼,并且很通用,在以后的項目中什么時候可以使用這種高封裝的api呢?當我們并不關心執行過程,只關心結果的時候,我們可以封裝一些這種有點函數式的api。很通用,并且其實并沒有降低代碼的可讀性。