Swift特立獨行的Emoji字數算法

閱讀時間約 4 分鐘
Emoji字數大學問?整死我了

Emoji字數大學問?整死我了

字數算法 = string.count?

在swift算一個string的字數時候,很直覺的會想到用.count來算

let s = "這是幾個字呢".count
print(s.count) // 6

毫無疑問的安心信賴6個字

表情符號的場合

let emoji = "😂"
print(emoji.count) // 1​

一個表情符號=1個字,乍看也是理所當然的,因為真的就出現一個字啊。

但在驗收時卻被QA開單,iOS的字數算法跟Android、Web不一樣。

於是把表情符號貼到google翻譯測試,發現神奇的事

2個字????

2個字????

Google算他是兩個字?!不死心再測試其他表符

🙏 swift = 1個字,google = 2個字

let emoji = "🙏"
print(emoji.count) // 1​
2個字

2個字

🙏🏾 swift = 1個字,google = 4個字

let emoji = "🙏🏾"
print(emoji.count) // 1​
4個字

4個字

👩‍👩‍👧‍👦 swift = 1個字,google = 11個字

let emoji = "👩‍👩‍👧‍👦"
print(emoji.count) // 1​
11個字

11個字

到底是幾個字????🤯

到底是幾個字????🤯

到底算幾個字

看上面的測試也很難做出一個總結,一般版emoji的算2個字,色違版的4個字。但家庭的emoji會算成11個字。然後swift全部算1個字又是怎麼回事?

馬上去查官方文件

Measuring the Length of a String

When you need to know the length of a string, you must first consider what you’ll use the length for. Are you measuring the number of characters that will be displayed on the screen, or are you measuring the amount of storage needed for the string in a particular encoding? A single string can have greatly differing lengths when measured by its different views.

一看完當頭棒喝🤯🤯🤯。官方表示你要算字數的時候,你必須知道自己要的是什麼。是要算螢幕上出現的字數呢?還是特定編碼下的字數?不同情境下算出的字數也會不同。

裡面舉了一個旗子emoji的範例

let flag = "🇵🇷"
print(flag.count)
// Prints "1"
print(flag.unicodeScalars.count)
// Prints "2"
print(flag.utf16.count)
// Prints "4"
print(flag.utf8.count)
// Prints "8"

所以count指的是螢幕上出現的字數,也就是一個字。

這邊我應該是要用的是UTF-16的算法,因為Android(java)跟Web(js)default都是UTF-16編碼。

馬上回去Playground測試

🙏 swift utf16 = 2個字

let emoji = "🙏"
print(emoji.utf16.count) // 2

🙏🏾 swift utf16 = 4個字

let emoji = "🙏🏾"
print(emoji.utf16.count) // 4

👩‍👩‍👧‍👦 swift utf16 = 11個字

let emoji = "👩‍👩‍👧‍👦"
print(emoji.utf16.count) // 1​1

完全吻合🥳🥳🥳

另外StackOverflow上有教另一種轉成NSString.length的算法,其實也是同理,背後是UTF-16

length

The number of UTF-16 code units in the receiver.

let emoji = "🙏🏾"
print(emoji as NSString).length) // 4
print(emoji.utf16.count) // 4


至於更多為什麼emoji會有那麼多不同長度,可以看這位dcard大大的文章,解釋的很詳細🎉



5會員
22內容數
紀錄iOS開發上遇到的問題或是一些流程筆記。主要都是Swift。
留言0
查看全部
發表第一個留言支持創作者!