2017-09-15 21 views
1

Swift 4改變了字符串的工作方式。但是,似乎已經變得更加複雜和不太可讀。任何人都可以簡化這個例子(只需獲取字符串的第三個字母作爲字符串)? (除了分裂出來的線條。)更簡單的字符串在Swift中切片4

let myString="abc" 
let thirdLetter = String(myString[myString.index(myString.startIndex, offsetBy: 2)]) 
+2

你是什麼意思簡化?不需要從它創建一個新的字符串'let thirdLetter = myString [myString.index(myString.startIndex,offsetBy:2)]'。順便說一句,你可以檢查這個答案https://stackoverflow.com/a/38215613/2303865。它將允許你使用Int'myString [2]'下標字符串' –

+2

通過簡化,我的意思是更容易理解和更容易編寫。對於一項簡單的任務,我對這種複雜性感到非常震驚。如果你沒有用String(...)來包裝它,那麼你最終會得到一個字符類型而不是字符串 –

+0

那麼這就是我期望的行爲,如果你只是得到一個字母,一個字符就是它應該是返回。上面鏈接的答案已經更新到Swift 4。它也支持部分範圍 –

回答

2

看來你正試圖提取第三個字符。我想說

let c = myString.prefix(3).last 

誠然,這是一個可選的性格,但你可以悠閒地拆開包裝並在需要時強制爲String。

prefix方法是非常有價值的,因爲它需要一個Int而不是強迫你進入String.Index的狂野世界。

+1

您不能「字符串」作爲字符串 –

+0

這也將返回第二個字符,第一個字符或甚至爲零字符短於3個字符。 –

+0

'myString.dropFirst(2).first'只是一個小小的變化,可以避免這個問題。 –

3

在斯威夫特4您可以將StringmyString轉換爲[Character]Array(myString)。然後你可以用Int索引該數組,然後將該數組轉換爲String

let myString = "abc" 
let thirdLetter = String(Array(myString)[2]) // "c" 
let firstTwo = String(Array(myString)[0..<2]) // "ab" 

如果你打算做很多操作上的String,經常最好只是轉換,並將其作爲[Character]


注意:爲了避免編譯器可能執行的任何緩存優化,我重新編寫了本節。現在每種方法只測量一次,併爲每種方法保留一個運行總數。

轉換爲Array和用Int編制索引很容易編寫和讀取,但它的性能如何?爲了回答這個問題,我測試了一個發佈版本如下:

func time1(str: String, n: Int) -> (Double, String) { 
    // Method 1: Index string with String.Index, convert to String 

    let start = Date() 
    let a = String(str[str.index(str.startIndex, offsetBy: n)]) 
    let interval = Date().timeIntervalSince(start) 

    return (interval, a) 
} 

func time2(str: String, n: Int) -> (Double, String) { 
    // Method 2: Convert string to array, index with Int, convert to String 

    let start = Date() 
    let a = String(Array(str)[n]) 
    let interval = Date().timeIntervalSince(start) 

    return (interval, a) 
} 


func time3(str: String, n: Int) -> (Double, String) { 
    // Method 3: Use prefix() and last(), convert to String 

    let start = Date() 
    let a = String(str.prefix(n + 1).last!) 
    let interval = Date().timeIntervalSince(start) 

    return (interval, a) 
} 

func time4(str: String, n: Int) -> (Double, String) { 
    // Method 4: Use Leo Dabus' extensions 
    // https://stackoverflow.com/q/24092884/1630618 

    let start = Date() 
    let a = str[n] 
    let interval = Date().timeIntervalSince(start) 

    return (interval, a) 
} 

func time5(str: String, n: Int) -> (Double, String) { 
    // Method 5: Same as 2 but don't measure Array conversion time 

    let arr = Array(str) 

    let start = Date() 
    let a = String(arr[n]) 
    let interval = Date().timeIntervalSince(start) 

    return (interval, a) 
} 

func test() { 
    for repetitions in [1, 10, 100, 1000] { 
     var input = "" 
     for _ in 0 ..< repetitions { 
      input.append("abcdefghijklmnopqrstuvwxyz") 
     } 

     var t = [0.0, 0.0, 0.0, 0.0, 0.0] 
     let funcs = [time1, time2, time3, time4, time5] 

     for i in 0 ..< input.count { 
      for f in funcs.indices { 
       let (interval, _) = funcs[f](input, i) 
       t[f] += interval 
      } 
     } 

     print("For string length \(input.count):") 
     for i in 0 ..< 5 { 
      print(String(format: "Method %d time: %.8f", i + 1, t[i])) 
     } 
     print("") 
    } 
} 

結果:

For string length 26: 
Method 1 time: 0.00108612 
Method 2 time: 0.00085294 
Method 3 time: 0.00005889 
Method 4 time: 0.00002104 
Method 5 time: 0.00000405 

For string length 260: 
Method 1 time: 0.00117570 
Method 2 time: 0.00670648 
Method 3 time: 0.00115579 
Method 4 time: 0.00110406 
Method 5 time: 0.00007111 

For string length 2600: 
Method 1 time: 0.09964919 
Method 2 time: 0.57621503 
Method 3 time: 0.09244329 
Method 4 time: 0.09166771 
Method 5 time: 0.00087011 

For string length 26000: 
Method 1 time: 9.78054154 
Method 2 time: 56.92994779 
Method 3 time: 9.02372885 
Method 4 time: 9.01480001 
Method 5 time: 0.03442019 

分析:

  1. 數組轉換爲昂貴,特別是隨着陣列尺寸的增加。
  2. 如果您可以保留轉換後的[Character],那麼對其進行的索引操作非常快。 (見方法5)
  3. 方法1,3和4的速度都差不多,所以根據自己的個人偏好進行選擇。
+1

我在一個真實的項目中做過。 – vacawama

+0

你能測試我的擴展,看看它是比使用字符數組更慢還是更快? –

+1

是的,我會測試它 – vacawama