localeCompare()的用法

Jun
appxtech
Published in
6 min readSep 17, 2020

在學typescript時,會介紹到localeCompare()這個function(函式),但localeCompare到底是什麼?以及怎麼用?

localeCompare在官網及一些文章的解釋為「依特定順序來比較二個字串」、「排序中文字串」、「中文排序比較」、「比較字符串」、「參考字符串與比較字符串的排序順序」。

你看的懂上面的解釋了嗎?如果你看懂了,恭喜你可以離開這個網頁了。但如果你和我一樣似懂非懂(像極了愛情),那希望下面的解說,可以讓你更清楚localeCompare的使用方式。

下面會依序
— — — — — localeCompare的簡單說明
— — — — — localeCompare使用方法
— — — — — localeCompare的原理

— — — — — localeCompare的問題
來做說明

localeCompare的簡單說明

localeCompare用最簡單的方式來說,就是「檔名的排序」。

在每個資料夾或網站的列表中,每個檔案或列表都會有一定的排序順序。用上圖來解釋的話,當你按下「名稱」,就會用名稱來做排序,而排序的結果就是由小到大,或由大到小,英文字母的A→B→C…。

也就是說,localeCompare()是在比較二個檔名是誰大誰小(或是相同)。

localeCompare使用方法

比較的字串.localeCompare(被比較的字串)。舉例

var str1 = “a”;var str2 = “b”;console.log(str1.localeCompare(str2)); // 輸出結果為-1

而回傳的值會有-1,1,0這三種。值-1,代表比較的字串比被比較的字串來的小(str1比str2來的小 = a比b小)。值1,代表比較的字串比被比較的字串來的大(str1比str2大 = a比b大)。值0,代表二個字串相同(str1和str2一樣 = a相同於b)。

localeCompare的原理

依目前測試的結果,localeCompare是以Unicode編碼來進行比對。

var str1 = “1”;var str2 = “a”;var str3 = “b”;console.log(str1.charCodeAt(0)); // 輸出結果 49console.log(str2.charCodeAt(0)); // 輸出結果 97console.log(str3.charCodeAt(0)); // 輸出結果 98console.log(str1.localeCompare(str2)); // 輸出結果 -1console.log(str2.localeCompare(str3)); // 輸出結果 -1

從上圖及輸出的結果得知,1、a、b、這三個數的Unicode的值,再彼此使用localeCompare進行二個字串的比較,得到的答案是只要Unicode若比對方小,則會返回-1。

這個結果在windows的檔案命名排序上也是如此,如下圖

若是發生在長檔案名,比對的方式會是把檔名拆解從第一個開始比對,如果第一個相同,再比對第二個,直到比對的結果不同或是字串全比對完為止。

var str1 = “test abc”;var str2 = “test bbc”;console.log(str1.localeCompare(str2)); // 輸出結果 -1// — — — — — — — — — — — — — — — — str1 = “9981”;str2 = “9763”;console.log(str1.localeCompare(str2)); // 輸出結果 1// — — — — — — — — — — — — — — — — str1 = “ab12”;str2 = “ab12”;console.log(str1.localeCompare(str2)); // 輸出結果 0

localeCompare的問題

在學習localeCompare時的迷思是,如果當比對的字串裡,其中一方比另一方長,甚至於是空白的話,那麼比對的結果為何?

var str1 = “test”;var str2 = “testa”;console.log(str1.localeCompare(str2)); // 輸出結果 -1// — — — — — — — — — — — — — — — — str1 = “test0”;str2 = “test”;console.log(str1.localeCompare(str2)); // 輸出結果 1// — — — — — — — — — — — — — — — — str1 = “test “;str2 = “test”;console.log(str1.localeCompare(str2)); // 輸出結果 1

從上面交叉比測試的結果來看,結論就是只要字串比對方長(包含空白),就一定比對方大,可解釋為無論Unicode的值為何,就是比沒有值(undefined或null)來的大。

另外,中文數字的比較,也不是我們從中文文意上去理解的大小順序。例如我們知道一比二小,二也比三小,且零是最小的數(文意上先不加入負來討論)。但在localeCompare的結果並非如此。

var str0 = “零”;var str1 = “一”;var str2 = “二”;var str3 = “三”;var str4 = “四”;var str5 = “五”;console.log(str0.charCodeAt(0)); // 輸出結果38646console.log(str1.charCodeAt(0)); // 輸出結果19968console.log(str2.charCodeAt(0)); // 輸出結果20108console.log(str3.charCodeAt(0)); // 輸出結果19977console.log(str4.charCodeAt(0)); // 輸出結果22235console.log(str5.charCodeAt(0)); // 輸出結果20116console.log(str1.localeCompare(str2)); // 一 比對 二 輸出結果 -1console.log(str2.localeCompare(str3)); // 二 比對 三 輸出結果 1console.log(str0.localeCompare(str5)); // 零 比對 五 輸出結果 1

從上面的code可以發現,在零到五中,一是最小的,所以一 比對 二,輸出結果為-1。但二比對三時,發現輸出結果為1,是因為二的Unicode比三來的大,所以在排序上二會比三來的大。而零的Unicode比一到五都來的大,所以零在比對一到五的結果,都會為1,而不是我們在中文文意上的最小的結果。

--

--