讓 Swift 的字串照數字規則比大小

當字串的內容是數字,或是包含數字時,比大小的結果往往令我們失望,不是我們想要的。

如上圖所示,我們希望字串 “16” 比 “2” 大,但 “16” < “2” 的結果卻是 true。這是因為字串比較時預設是一個一個字 PK,所以會先比第一個字,因為 1 < 2,所以 “16” 小於 “2”。

若是字串內容都是數字,可以先將字串轉成數字,然後以我們熟悉的數字規則比大小。

let text1 = "16"let text2 = "2"if let number1 = Int(text1), let number2 = Int(text2) {   print(number1 < number2)}

但是此方法有點麻煩,因為字串轉數字會變成 optional ,還要檢查是否轉換成功,而且只適用字串內容全是數字的情況。

其實搭配字串的 function compare(_:options:range:locale:),即可讓它照數字的規則比大小。

func compare<T>(_ aString: T, options mask: String.CompareOptions = default, range: Range<Self.Index>? = default, locale: Locale? = default) -> ComparisonResult where T : StringProtocol

String.CompareOptions 型別的參數 mask 決定字串如何比大小,如果想像數字一樣比,可使用 String.CompareOptions.numeric。

範例

let text1 = "曲目16"let text2 = "曲目2"let result = text1.compare(text2, options: .numeric)if result == .orderedAscending {   print("\(text2) > \(text1)")} else {   print("\(text2) <= \(text1)")}

結果

compare 回傳結果的型別為 enum 定義的 ComparisonResult,有 orderedAscending(上升,前者小於後者),orderedSame(一樣),orderedDescending (下降,前者大於後者)三種 case。因此我們可從剛剛例子的 result 判斷誰大誰小。

此方法也可以使用在 array 的排序,例如以下例子

var songs = ["曲目16", "曲目2"]songs.sort { (text1, text2) -> Bool in   return text1.compare(text2, options: .numeric) == .orderedAscending}songs

彼得潘的 iOS App Neverland

Written by

彼得潘的 Swift 程式設計入門,App程式設計入門作者,彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,http://apppeterpan.strikingly.com

彼得潘的 Swift iOS App 開發問題解答集

彼得潘和學生們在開發 iOS App 路上曾經解決的問題集

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade