天天看點

Swift - 字元串(String)Q1Q2參考連結

在實際操作字元串中,會遇到很多坑,記錄一下别人遇到的坑,避免自己掉進去。

Q1

問題描述

var stack = Array<String>()  
stack.append("2.3")  
let lastElement = stack.popLast()!  
print("Popped last element: \(lastElement)")  
let number = NSNumberFormatter().numberFromString(lastElement)  
print("NSNumber gives us: \(lastElement)")  
let doubleValue = number!.doubleValue  
print("Double value of this element is: \(doubleValue)")      

上述代碼在Playground 以及iOS 模拟器中執行結果如下:

Popped last element: 2.3  
NSNumber gives us: 2.3  
Double value of this element is: 2.3      

但是在真機裡是這樣的:

Popped last element: 2.3  
NSNumber gives us: 2.3  
fatal error: unexpectedly found nil while unwrapping an Optional value  
(lldb)      

是以提問者修改了一行代碼:

let doubleValue = number?.doubleValue      

再次執行:

Popped last element: 2.3  
NSNumber gives us: 2.3  
Double value of this element is: nil      

發現解包失敗,值為 nil,那麼問題出在那裡呢?

解答

由junkpile解答:

你的手機所處國家可能對小數分隔符的定義是一個逗号‘,’,而不是句号‘.’

最後提問者現身說法,确實他設定的德國是使用逗号作為小數分隔符的,是以解包失敗。

junkpile 還給出了一個小建議:

在需要對數字字元串進行格式化的地方,比如輸入數字的使用者控件,你就需要顯式的指定數字格式的本地化屬性。反之在接收使用者輸入的數字時,你應該判斷本地化屬性,讓一切盡在掌握中。

Q2

問題描述

這個問題在實戰中經常被提及,譬如現在有一個字元串URL:https://api.github.com/gists/public?page=2,我需要從中提取出“?page=2”以及“https://api.github.com/gists/public”,将這兩個部分存儲到兩個變量中,如下:

var strBase = "https://api.github.com/gists/public"
var strPage = "?page=2"      

問題解答前了解下小知識:

  • HTTP GET請求中,url 與請求參數之間用?分隔,參數與參數之間是&分隔。

問題解答

思路:顯而易見,關注點應該放在?上,解決方式也五花八門,現提供以下幾種方式:

  • 方法一
var urlStr = "https://api.github.com/gists/public?page=2"
var strBase:String        // 請求位址
var strPage:String        // 請求參數

if let qIndex = urlStr.characters.indexOf("?") {  //35
// 2
strBase = urlStr.substringToIndex(qIndex)
strPage = urlStr.substringFromIndex(qIndex)
} else {
// 3
strBase = urlStr
strPage = ""
}      
  1. 首先定位到 ? 的 index 索引值。
  2. 請求位址中存在參數(即存在?),那麼通過

    substringToIndex

     和 

    substringFromIndex

     擷取到兩個部分
  3. 請求位址中不存在參數,那麼直接傳入的位址就是

    strBase

這裡的

qIndex

是一個索引值,類型是

String.CharacterView.Index

,修改該值并非是用 

+、-

 操作,而是調用

qIndex.successor()

 取到下一位索引值,使用

qIndex.predecessor()

取到前一位索引值。

對于

substringToIndex(qIndex)

方法,從 urlStr 的 

startIndex(這裡是0)

 開始截取直到 

qIndex

;對于

substringFromIndex(qIndex)

 方法,即從 

qIndex

 索引開始直到

endIndex

前面一個索引,為什麼這麼說?舉個例子,“Hello”字元的 startIndex 毫無疑問是等于0,但 endIndex 不是等于4!!而是5!!最後一個字元的後一位!希望大家記住。

  • 方法二

這裡是使用了

componentsSeparatedByString

方法,通過?字元将字元串分隔符将原字元串分割成多個部分到數組中。

let parts = urlStr.componentsSeparatedByString("?")
// 1
strBase = parts[0]
// 2
strPage = parts.count >= 2 ? "?" + parts[1] : ""      
  1. 顯然這裡隻有一個 ? 字元,将原字元串分割成兩個部分,第一個部分當然是 strBase 喽
  2. 通過數組的count 來判斷是否存在請求參數。
  • 方法三

    這裡使用了 NSURLComponents 方法:

if let urlCompo = NSURLComponents(string: urlStr) {
strPage = urlCompo.query != nil ? "?" + urlCompo.query! : ""
urlCompo.query = nil
strBase = urlCompo.string!
} else {
fatalError("invalid URL")
}      

參考連結

Q1原文連結

Q2原文連結

轉載于:https://www.cnblogs.com/KilinLee/p/5105800.html