【澳门葡京备用网址】取下标及品质难点

斯威夫特 中 String 取下标及质量难点

取下标

斯威夫特 中 String 取下标及质量难点

    在OC中数组,字典,会集有谈得来的代表方法,分别是Array,Dictionary,Set
与 String 都属于数值类型变量,他们都属于结构体。
使用简要介绍灵活多变,个人认为可读性别变化差了数不胜数,用起来由点别扭,还亟需稳步适应。
基本上功效都是照办OC的,首要总结成立,增,删,改,查,遍历。下边从数组伊始聊到。

取下标

String

String 用 String.Index 取下标(subscript)得到 Character,String.Index
要从 String 中获取

let greeting = "Guten Tag!"greeting[greeting.startIndex] // Character "G"greeting[greeting.index(before: greeting.endIndex)] // Character "!"greeting[greeting.index(after: greeting.startIndex)] // Character "u"let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // Character "a"

String 用 Range<String.Index> 或 ClosedRange<String.Index>
(以下 Range 和 ClosedRange 统称为 Range) 取下标获得 String

let str = "abc"str[str.startIndex..<str.index(after: str.startIndex)] // String "a"str[str.startIndex...str.index(after: str.startIndex)] // String "ab"

取下标

    一. Array ,数组,线性机构,按顺序存款和储蓄结构,有对应的下表标

String

String 用 String.Index 取下标(subscript)得到 Character,String.Index
要从 String 中获取

let greeting = "Guten Tag!"
greeting[greeting.startIndex] // Character "G"
greeting[greeting.index(before: greeting.endIndex)] // Character "!"
greeting[greeting.index(after: greeting.startIndex)] // Character "u"
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // Character "a"

String 用 Range<String.Index> 或 ClosedRange<String.Index>
(以下 Range 和 ClosedRange 统称为 Range) 取下标获得 String

let str = "abc"
str[str.startIndex..<str.index(after: str.startIndex)] // String "a"
str[str.startIndex...str.index(after: str.startIndex)] // String "ab"

Character

String 通过 characters 属性获得String.CharacterView,表示显示屏上显示的始末。String.CharacterView 通过
String.CharacterView.Index 取下标得到Character,String.CharacterView.Index 要从 String.CharacterView 中获取

let str = "abc"let characters = str.characters // String.CharacterViewcharacters[characters.startIndex] // Character "a"

注意,String.CharacterView 不依据 RandomAccessCollection 协议,用
String.CharacterView.Index
取下标不得以随意走访。
另外,String.CharacterView.Index 与
String.Index 是一律的花色,属于 Struct
。String.Index 的文书档案在 String
文书档案下

typealias Index = String.CharacterView.Index

String.CharacterView 通过 Range<String.CharacterView.Index> 得到
String.CharacterView。用 Character 和 String.CharacterView 都足以生成
String

let str = "abc"let characters = str.characters // String.CharacterViewlet characters2 = characters[characters.startIndex..<characters.index(after: characters.startIndex)] // String.CharacterViewString(characters.first!) == String(characters2) // true. characters.first! is Character

用 String.CharacterView 生成 Array<Character>,可以用
Int、Range<Int> 取下标。用 Array<Character> 也足以生成
String

let str = "abc"let arr = Array(str.characters) // Array<Character> ["a", "b", "c"]arr[1] // Character "b"arr[1...2] // ArraySlice<Character> ["b", "c"]String(arr) // String "abc"

Character 能够平昔与 “a” 相比较

let str = "abc"let a = str[str.startIndex] // Character "a"let b = str[str.index(str.startIndex, offsetBy: 1)] // Character "b"a == "a" // trueb > "a" // true

String

String 用 String.Index 取下标(subscript)得到 Character,String.Index
要从 String 中获取

let greeting = "Guten Tag!"
greeting[greeting.startIndex] // Character "G"
greeting[greeting.index(before: greeting.endIndex)] // Character "!"
greeting[greeting.index(after: greeting.startIndex)] // Character "u"
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // Character "a"

String 用 Range<String.Index> 或 ClosedRange<String.Index>
(以下 Range 和 ClosedRange 统称为 Range) 取下标得到 String

let str = "abc"
str[str.startIndex..<str.index(after: str.startIndex)] // String "a"
str[str.startIndex...str.index(after: str.startIndex)] // String "ab"

       创设格局贼多,我们依照本人的喜好随意选壹种啊,

Character

String 通过 characters 属性得到String.CharacterView,表示显示器上显得的剧情。String.CharacterView 通过
String.CharacterView.Index 取下标得到Character,String.CharacterView.Index 要从 String.CharacterView 中收获

let str = "abc"
let characters = str.characters // String.CharacterView
characters[characters.startIndex] // Character "a"

注意,String.CharacterView 不坚守 RandomAccessCollection 协议,用
String.CharacterView.Index
取下标不可能私行走访。
另外,String.CharacterView.Index 与
String.Index 是千篇一律的体系,属于 Struct
。String.Index 的文书档案在 String
文书档案下

typealias Index = String.CharacterView.Index

String.CharacterView 通过 Range<String.CharacterView.Index> 得到
String.CharacterView。用 Character 和 String.CharacterView 都足以生成
String

let str = "abc"
let characters = str.characters // String.CharacterView
let characters2 = characters[characters.startIndex..<characters.index(after: characters.startIndex)] // String.CharacterView
String(characters.first!) == String(characters2) // true. characters.first! is Character

用 String.CharacterView 生成 Array<Character>,可以用
Int、Range<Int> 取下标。用 Array<Character> 也得以生成
String

let str = "abc"
let arr = Array(str.characters) // Array<Character> ["a", "b", "c"]
arr[1] // Character "b"
arr[1...2] // ArraySlice<Character> ["b", "c"]
String(arr) // String "abc"

Character 能够一贯与 “a” 相比较

let str = "abc"
let a = str[str.startIndex] // Character "a"
let b = str[str.index(str.startIndex, offsetBy: 1)] // Character "b"
a == "a" // true
b > "a" // true

UTF-8

String 通过 utf八 属性得到 String.UTF八View,表示 UTF-8编码的始末。String.UTF8View 通过 String.UTF八View.Index 取下标获得UTF八.CodeUnit,实际上是 UInt八;通过 Range<String.UTF8View.Index>
取下标获得 String.UTF8View。String.UTF八View.Index 要从 String.UTF八View
中获得。String.UTF8View 不遵从 RandomAccessCollection 协议,用
String.UTF捌View.Index 取下标不得以自由访问。
用 String.UTF8View 生成
Array<UInt8>,可以用 Int、Range<Int> 取下标。
String.UTF捌View 能够生成 String。
用 UInt八 或 Array<UInt八>
也能够生成 String,但内容表示数字或数字数组,不是数字的 UTF-八 编码内容。

let str = "abc"let utf8 = str.utf8 // String.UTF8Viewlet n = utf8[utf8.startIndex] // UInt8 97let a = utf8[utf8.startIndex..<utf8.index(after: utf8.startIndex)] // String.UTF8View "a"let ab = utf8[utf8.startIndex...utf8.index(after: utf8.startIndex)] // String.UTF8View "ab"String(n) // "97", NOT "a"String(a) // "a"String(ab) // "ab"let arr = Array(utf8) // Array<UInt8> [97, 98, 99]let n2 = arr[0] // UInt8 97let arr2 = arr[0...1] // // ArraySlice<UInt8> [97, 98]

String 通过 utf八CString 属性获得 ContiguousArray<CChar>,实际上是
ContiguousArray<Int8>,表示 UTF-8 编码的始末还要最后扩张贰个0,所以长度比 utf8 属性的长度大 一。ContiguousArray<Int八> 能够用
Int、Range<Int> 取下标,分别赢得 Int捌 和
ArraySlice<Int八>。ContiguousArray 服从 RandomAccessCollection
协议,用 Int 取下标能够私自走访。

let str = "abc"let utf8 = str.utf8CString // ContiguousArray<Int8> [97, 98, 99, 0]let a = utf8[0] // Int8 97let ab = utf8[0...1] // ArraySlice<Int8> [97, 98]

Character

String 通过 characters 属性得到String.CharacterView,表示显示屏上出示的剧情。String.CharacterView 通过
String.CharacterView.Index 取下标得到Character,String.CharacterView.Index 要从 String.CharacterView 中赢得

let str = "abc"
let characters = str.characters // String.CharacterView
characters[characters.startIndex] // Character "a"

注意,String.CharacterView 不遵守 RandomAccessCollection 协议,用
String.CharacterView.Index
取下标不能够私下访问。
另外,String.CharacterView.Index 与
String.Index 是同样的种类,属于 Struct
。String.Index 的文书档案在 String
文书档案下

typealias Index = String.CharacterView.Index

String.CharacterView 通过 Range<String.CharacterView.Index> 得到
String.CharacterView。用 Character 和 String.CharacterView 都得以生成
String

let str = "abc"
let characters = str.characters // String.CharacterView
let characters2 = characters[characters.startIndex..<characters.index(after: characters.startIndex)] // String.CharacterView
String(characters.first!) == String(characters2) // true. characters.first! is Character

用 String.CharacterView 生成 Array<Character>,可以用
Int、Range<Int> 取下标。用 Array<Character> 也得以生成
String

let str = "abc"
let arr = Array(str.characters) // Array<Character> ["a", "b", "c"]
arr[1] // Character "b"
arr[1...2] // ArraySlice<Character> ["b", "c"]
String(arr) // String "abc"

Character 能够直接与 “a” 比较

let str = "abc"
let a = str[str.startIndex] // Character "a"
let b = str[str.index(str.startIndex, offsetBy: 1)] // Character "b"
a == "a" // true
b > "a" // true

        var firstArray:Array<Int> = Array<Int>() 

【澳门葡京备用网址】取下标及品质难点。UTF-8

String 通过 utf8 属性得到 String.UTF八View,表示 UTF-八编码的剧情。String.UTF8View 通过 String.UTF8View.Index 取下标得到UTF8.CodeUnit,实际上是 UInt八;通过 Range<String.UTF捌View.Index>
取下标获得 String.UTF捌View。String.UTF捌View.Index 要从 String.UTF八View
中获取。String.UTF八View 不遵照 RandomAccessCollection 协议,用
String.UTF八View.Index 取下标不得以随便走访。
用 String.UTF8View 生成
Array<UInt8>,可以用 Int、Range<Int> 取下标。
String.UTF8View 能够生成 String。
用 UInt八 或 Array<UInt8>
也足以生成 String,但剧情表示数字或数字数组,不是数字的 UTF-八 编码内容。

let str = "abc"
let utf8 = str.utf8 // String.UTF8View
let n = utf8[utf8.startIndex] // UInt8 97
let a = utf8[utf8.startIndex..<utf8.index(after: utf8.startIndex)] // String.UTF8View "a"
let ab = utf8[utf8.startIndex...utf8.index(after: utf8.startIndex)] // String.UTF8View "ab"
String(n) // "97", NOT "a"
String(a) // "a"
String(ab) // "ab"

let arr = Array(utf8) // Array<UInt8> [97, 98, 99]
let n2 = arr[0] // UInt8 97
let arr2 = arr[0...1] // // ArraySlice<UInt8> [97, 98]

String 通过 utf八CString 属性获得 ContiguousArray<CChar>,实际上是
孔蒂guousArray<Int八>,表示 UTF-8 编码的剧情还要最终扩大三个0,所以长度比 utf8 属性的长度大 一。ContiguousArray<Int捌> 能够用
Int、Range<Int> 取下标,分别拿到 Int八 和
ArraySlice<Int八>。ContiguousArray 坚守 RandomAccessCollection
协议,用 Int 取下标能够私自走访。

let str = "abc"
let utf8 = str.utf8CString // ContiguousArray<Int8> [97, 98, 99, 0]
let a = utf8[0] // Int8 97
let ab = utf8[0...1] // ArraySlice<Int8> [97, 98]

UTF-16

String 通过 utf1陆 属性得到 String.UTF16View,表示 UTF-1陆编码的始末。String.UTF1陆View 通过 String.UTF16View.Index 取下标得到UTF1陆.CodeUnit,实际上是 UInt1陆;通过
Range<String.UTF1六View.Index> 取下标得到String.UTF1六View。String.UTF1陆View.Index 要从 String.UTF1六View
中收获。String.UTF16View 遵从 RandomAccessCollection 协议,用
String.UTF16View.Index 取下标能够自便访问。
用 String.UTF16View 生成
Array<UInt16>,可以用 Int、Range<Int> 取下标。
String.UTF16View 能够生成 String。
用 UInt1陆 或 Array<UInt16>
也得以生成 String,但剧情表示数字或数字数组,不是数字的 UTF-16编码内容。

let str = "abc"let utf16 = str.utf16 // String.UTF16Viewlet n = utf16[utf16.startIndex] // UInt16 97let a = utf16[utf16.startIndex..<utf16.index(after: utf16.startIndex)] // String.UTF16View "a"let ab = utf16[utf16.startIndex...utf16.index(after: utf16.startIndex)] // String.UTF16View "ab"String(n) // "97", NOT "a"String(a) // "a"String(ab) // "ab"let arr = Array(utf16) // Array<UInt16> [97, 98, 99]let n2 = arr[0] // UInt16 97let arr2 = arr[0...1] // // ArraySlice<UInt8> [97, 98]

UTF-8

String 通过 utf八 属性获得 String.UTF捌View,表示 UTF-8编码的始末。String.UTF八View 通过 String.UTF捌View.Index 取下标得到UTF捌.CodeUnit,实际上是 UInt八;通过 Range<String.UTF八View.Index>
取下标获得 String.UTF八View。String.UTF8View.Index 要从 String.UTF八View
中赢得。String.UTF捌View 不根据 RandomAccessCollection 协议,用
String.UTF捌View.Index 取下标不得以随便走访。
用 String.UTF8View 生成
Array<UInt8>,可以用 Int、Range<Int> 取下标。
String.UTF八View 能够生成 String。
用 UInt八 或 Array<UInt8>
也足以生成 String,但剧情表示数字或数字数组,不是数字的 UTF-捌 编码内容。

let str = "abc"
let utf8 = str.utf8 // String.UTF8View
let n = utf8[utf8.startIndex] // UInt8 97
let a = utf8[utf8.startIndex..<utf8.index(after: utf8.startIndex)] // String.UTF8View "a"
let ab = utf8[utf8.startIndex...utf8.index(after: utf8.startIndex)] // String.UTF8View "ab"
String(n) // "97", NOT "a"
String(a) // "a"
String(ab) // "ab"

let arr = Array(utf8) // Array<UInt8> [97, 98, 99]
let n2 = arr[0] // UInt8 97
let arr2 = arr[0...1] // // ArraySlice<UInt8> [97, 98]

String 通过 utf八CString 属性获得 孔蒂guousArray<CChar>,实际上是
ContiguousArray<Int八>,表示 UTF-八 编码的剧情还要最后扩充二个0,所以长度比 utf八 属性的长短大 一。ContiguousArray<Int八> 能够用
Int、Range<Int> 取下标,分别获得 Int八 和
ArraySlice<Int八>。ContiguousArray 服从 RandomAccessCollection
协议,用 Int 取下标能够轻松访问。

let str = "abc"
let utf8 = str.utf8CString // ContiguousArray<Int8> [97, 98, 99, 0]
let a = utf8[0] // Int8 97
let ab = utf8[0...1] // ArraySlice<Int8> [97, 98]

        var secondArray:Array = Array<Int>()

UTF-16

String 通过 utf16 属性得到 String.UTF1六View,表示 UTF-1六编码的剧情。String.UTF1陆View 通过 String.UTF1陆View.Index 取下标得到UTF1陆.CodeUnit,实际上是 UInt1六;通过
Range<String.UTF16View.Index> 取下标获得String.UTF16View。String.UTF1陆View.Index 要从 String.UTF16View
中获得。String.UTF1六View 遵从 RandomAccessCollection 协议,用
String.UTF1六View.Index 取下标能够率性访问。
用 String.UTF16View 生成
Array<UInt16>,可以用 Int、Range<Int> 取下标。
String.UTF16View 能够生成 String。
用 UInt16 或 Array<UInt1陆>
也得以生成 String,但内容表示数字或数字数组,不是数字的 UTF-16编码内容。

let str = "abc"
let utf16 = str.utf16 // String.UTF16View
let n = utf16[utf16.startIndex] // UInt16 97
let a = utf16[utf16.startIndex..<utf16.index(after: utf16.startIndex)] // String.UTF16View "a"
let ab = utf16[utf16.startIndex...utf16.index(after: utf16.startIndex)] // String.UTF16View "ab"
String(n) // "97", NOT "a"
String(a) // "a"
String(ab) // "ab"

let arr = Array(utf16) // Array<UInt16> [97, 98, 99]
let n2 = arr[0] // UInt16 97
let arr2 = arr[0...1] // // ArraySlice<UInt8> [97, 98]

属性相比


String、String.CharacterView、Array<Character>、String.UTF八View、Array<UInt8>、ContiguousArray<Int八>、String.UTF1陆View、Array<UInt1陆>
实行判空(isEmpty)、获取长度(count)、1个职位的取下标([index])、一段距离的取下标([range])测试,总结施行时间。

概念测试项目、打字与印刷和更新时间的措施、要测试的 String

import Foundationenum TestType {    case isEmpty    case count
    case index    case range
}func printAndUpdateTime(_ date: inout Date) {    let now = Date()    print(now.timeIntervalSince(date))
    date = now
}let s = "aasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafcpiluioufnlkqjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjliopjktyuljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasderwytwghfsdfsdfgfdsg vrutj7edbj7 fdgotuyoergcwhmkl5lknjklqawkyrcqjljkljqjlqjhbrlqwfcbhafci luioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcvcnvbwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjkn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg iopiouvrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkfghngdljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmbkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqasdfsdwkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljdqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasddfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbsdfdsrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfsadfsdgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqsdfasjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdafgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlk"

测试代码

let loopCount = 10000let index = s.characters.count / 2let testType: TestType = .rangeprint(testType)var date = Date()

forLoop: for _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = s.isEmpty    case .count:        break forLoop    case .index:        _ = s[s.index(s.startIndex, offsetBy: index)]    case .range:        let endIndex = s.index(s.startIndex, offsetBy: index)        _ = s[s.startIndex..<endIndex]
    }
}if testType == .count {
    date = Date()
} else {    print("String")
    printAndUpdateTime(&date)
}let characters = s.charactersfor _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = characters.isEmpty    case .count:        _ = characters.count
    case .index:        _ = characters[characters.index(characters.startIndex, offsetBy: index)]    case .range:        let endIndex = characters.index(characters.startIndex, offsetBy: index)        _ = characters[characters.startIndex..<endIndex]
    }
}print("Characters")
printAndUpdateTime(&date)let characterArr = Array(characters)for _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = characterArr.isEmpty    case .count:        _ = characterArr.count
    case .index:        _ = characterArr[index]    case .range:        _ = characterArr[0..<index]
    }
}print("Characters array")
printAndUpdateTime(&date)let utf8 = s.utf8for _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = utf8.isEmpty    case .count:        _ = utf8.count
    case .index:        _ = utf8[utf8.index(utf8.startIndex, offsetBy: index)]    case .range:        let endIndex = utf8.index(utf8.startIndex, offsetBy: index)        _ = utf8[utf8.startIndex..<endIndex]
    }
}print("UTF-8")
printAndUpdateTime(&date)let utf8Arr = Array(utf8)for _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = utf8Arr.isEmpty    case .count:        _ = utf8Arr.count
    case .index:        _ = utf8Arr[index]    case .range:        _ = utf8Arr[0..<index]
    }
}print("UTF-8 array")
printAndUpdateTime(&date)let utf8CString = s.utf8CStringfor _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = utf8CString.isEmpty    case .count:        _ = utf8CString.count
    case .index:        _ = utf8CString[index]    case .range:        _ = utf8CString[0..<index]
    }
}print("UTF-8 C string")
printAndUpdateTime(&date)let utf16 = s.utf16for _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = utf16.isEmpty    case .count:        _ = utf16.count
    case .index:        _ = utf16[utf16.index(utf16.startIndex, offsetBy: index)]    case .range:        let endIndex = utf16.index(utf16.startIndex, offsetBy: index)        _ = utf16[utf16.startIndex..<endIndex]
    }
}print("UTF-16")
printAndUpdateTime(&date)let utf16Arr = Array(utf16)for _ in 0..<loopCount {    switch testType {    case .isEmpty:        _ = utf16Arr.isEmpty    case .count:        _ = utf16Arr.count
    case .index:        _ = utf16Arr[index]    case .range:        _ = utf16Arr[0..<index]
    }
}print("UTF-16 array")
printAndUpdateTime(&date)

测试结果

判空

澳门葡京备用网址 1

赢得长度

澳门葡京备用网址 2

叁个岗位的取下标

澳门葡京备用网址 3

壹段距离的取下标

澳门葡京备用网址 4

以上比较中,判别 String 是或不是为空,访问 String 的 isEmpty
速度最快。对于其余操作,服从 RandomAccessCollection
协议(孔蒂guousArray<Int8>、String.UTF1陆View 以及其它Array)的门类作用较高。

越是比较判空操作

let loopCount = 10000var date = Date()for _ in 0..<loopCount {    _ = s.isEmpty
}print("isEmpty")
printAndUpdateTime(&date)for _ in 0..<loopCount {    _ = s == ""}print("== \"\"")
printAndUpdateTime(&date)

澳门葡京备用网址 5

与走访 String 的 isEmpty 比较,决断 String 是不是等于空 String
速度更加快!

只顾到文书档案中,对 String.UTF八View 和 String.UTF1陆View 的 Range
取下标方法的证实

subscript(bounds: Range<String.UTF8View.Index>) -> String.UTF8View { get }subscript(bounds: Range<String.UTF16View.Index>) -> String.UTF16View { get }

Complexity: O(n) if the underlying string is bridged from Objective-C, where n is the length of the string; otherwise, O(1).

尽管 String 是从 Objective-C 的 NSString 桥接来的,时间复杂度为
O(n),不然为 O(一)。那句话怎么领会啊?后边说了,String.UTF八View 不依照RandomAccessCollection 协议,而 String.UTF1陆View 服从RandomAccessCollection
协议,两者的大运复杂度应该例外。那里怎么说时间复杂度与 String 是不是桥接自
NSString 有关?以下进一步追究。

let s2 = NSString(string: s) as Stringlet loopCount = 10000let index = s.characters.count / 2let index2 = s.characters.count - 1func test(_ s: String) {    var date = Date()    
    let utf8 = s.utf8    for _ in 0..<loopCount {        _ = utf8[utf8.startIndex..<utf8.index(utf8.startIndex, offsetBy: index)]
    }    
    print("UTF-8 index")
    printAndUpdateTime(&date)    
    for _ in 0..<loopCount {        _ = utf8[utf8.startIndex..<utf8.index(utf8.startIndex, offsetBy: index2)]
    }    
    print("UTF-8 index2")
    printAndUpdateTime(&date)    
    let utf16 = s.utf16    for _ in 0..<loopCount {        _ = utf16[utf16.startIndex..<utf16.index(utf16.startIndex, offsetBy: index)]
    }    
    print("UTF-16 index")
    printAndUpdateTime(&date)    
    for _ in 0..<loopCount {        _ = utf16[utf16.startIndex..<utf16.index(utf16.startIndex, offsetBy: index2)]
    }    
    print("UTF-16 index2")
    printAndUpdateTime(&date)
}print("String")
test(s)print("\nString bridged from NSString")
test(s2)

测试结果

澳门葡京备用网址 6

相比较 index 与 index2 的异样。测试参数 index二 约为 index 的 二 倍。UTF-捌index2 的耗费时间也约为 index 的 二 倍。UTF-1陆 的 index 和 index贰耗费时间周围。那与是还是不是比照 RandomAccessCollection 协议壹致。

相对来说 String 与 NSString 的出入。桥接自 NSString 的 String 耗费时间比 String
要长,UTF-8 越发明显。那应该正是文书档案表达的境况。用 Range
取下标,桥接自 NSString 的 String,比 String 多一些操作,多出 O(n)
品级的流年
,而不是取下标的刻钟复杂度是 O(n)。

UTF-16

String 通过 utf1陆 属性得到 String.UTF1六View,表示 UTF-1陆编码的剧情。String.UTF1陆View 通过 String.UTF1陆View.Index 取下标获得UTF1陆.CodeUnit,实际上是 UInt16;通过
Range<String.UTF1陆View.Index> 取下标获得String.UTF1陆View。String.UTF1陆View.Index 要从 String.UTF16View
中赚取。String.UTF1陆View 遵从 RandomAccessCollection 协议,用
String.UTF1陆View.Index 取下标能够私自走访。
用 String.UTF16View 生成
Array<UInt16>,可以用 Int、Range<Int> 取下标。
String.UTF1陆View 能够生成 String。
用 UInt16 或 Array<UInt1陆>
也得以生成 String,但内容表示数字或数字数组,不是数字的 UTF-1六编码内容。

let str = "abc"
let utf16 = str.utf16 // String.UTF16View
let n = utf16[utf16.startIndex] // UInt16 97
let a = utf16[utf16.startIndex..<utf16.index(after: utf16.startIndex)] // String.UTF16View "a"
let ab = utf16[utf16.startIndex...utf16.index(after: utf16.startIndex)] // String.UTF16View "ab"
String(n) // "97", NOT "a"
String(a) // "a"
String(ab) // "ab"

let arr = Array(utf16) // Array<UInt16> [97, 98, 99]
let n2 = arr[0] // UInt16 97
let arr2 = arr[0...1] // // ArraySlice<UInt8> [97, 98]

        var thirdArray = Array<Int>()

属性相比较


String、String.CharacterView、Array<Character>、String.UTF8View、Array<UInt八>、ContiguousArray<Int八>、String.UTF16View、Array<UInt1陆>
实行判空(isEmpty)、获取长度(count)、多少个职位的取下标([index])、1段距离的取下标([range])测试,总括实践时间。

概念测试项目、打字与印刷和更新时间的主意、要测试的 String

import Foundation

enum TestType {
    case isEmpty
    case count
    case index
    case range
}

func printAndUpdateTime(_ date: inout Date) {
    let now = Date()
    print(now.timeIntervalSince(date))
    date = now
}

let s = "aasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafcpiluioufnlkqjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjliopjktyuljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasderwytwghfsdfsdfgfdsg vrutj7edbj7 fdgotuyoergcwhmkl5lknjklqawkyrcqjljkljqjlqjhbrlqwfcbhafci luioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcvcnvbwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjkn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg iopiouvrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkfghngdljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmbkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqasdfsdwkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljdqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasddfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbsdfdsrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfsadfsdgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqsdfasjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdafgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlk"

测试代码

let loopCount = 10000
let index = s.characters.count / 2
let testType: TestType = .range
print(testType)
var date = Date()

forLoop: for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = s.isEmpty
    case .count:
        break forLoop
    case .index:
        _ = s[s.index(s.startIndex, offsetBy: index)]
    case .range:
        let endIndex = s.index(s.startIndex, offsetBy: index)
        _ = s[s.startIndex..<endIndex]
    }
}

if testType == .count {
    date = Date()
} else {
    print("String")
    printAndUpdateTime(&date)
}

let characters = s.characters
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = characters.isEmpty
    case .count:
        _ = characters.count
    case .index:
        _ = characters[characters.index(characters.startIndex, offsetBy: index)]
    case .range:
        let endIndex = characters.index(characters.startIndex, offsetBy: index)
        _ = characters[characters.startIndex..<endIndex]
    }
}

print("Characters")
printAndUpdateTime(&date)

let characterArr = Array(characters)
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = characterArr.isEmpty
    case .count:
        _ = characterArr.count
    case .index:
        _ = characterArr[index]
    case .range:
        _ = characterArr[0..<index]
    }
}

print("Characters array")
printAndUpdateTime(&date)

let utf8 = s.utf8
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf8.isEmpty
    case .count:
        _ = utf8.count
    case .index:
        _ = utf8[utf8.index(utf8.startIndex, offsetBy: index)]
    case .range:
        let endIndex = utf8.index(utf8.startIndex, offsetBy: index)
        _ = utf8[utf8.startIndex..<endIndex]
    }
}

print("UTF-8")
printAndUpdateTime(&date)

let utf8Arr = Array(utf8)
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf8Arr.isEmpty
    case .count:
        _ = utf8Arr.count
    case .index:
        _ = utf8Arr[index]
    case .range:
        _ = utf8Arr[0..<index]
    }
}

print("UTF-8 array")
printAndUpdateTime(&date)

let utf8CString = s.utf8CString
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf8CString.isEmpty
    case .count:
        _ = utf8CString.count
    case .index:
        _ = utf8CString[index]
    case .range:
        _ = utf8CString[0..<index]
    }
}

print("UTF-8 C string")
printAndUpdateTime(&date)

let utf16 = s.utf16
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf16.isEmpty
    case .count:
        _ = utf16.count
    case .index:
        _ = utf16[utf16.index(utf16.startIndex, offsetBy: index)]
    case .range:
        let endIndex = utf16.index(utf16.startIndex, offsetBy: index)
        _ = utf16[utf16.startIndex..<endIndex]
    }
}

print("UTF-16")
printAndUpdateTime(&date)

let utf16Arr = Array(utf16)
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf16Arr.isEmpty
    case .count:
        _ = utf16Arr.count
    case .index:
        _ = utf16Arr[index]
    case .range:
        _ = utf16Arr[0..<index]
    }
}

print("UTF-16 array")
printAndUpdateTime(&date)

测试结果

判空

澳门葡京备用网址 7

赢得长度

澳门葡京备用网址 8

3个岗位的取下标

澳门葡京备用网址 9

1段距离的取下标

澳门葡京备用网址 10

如上相比较中,判别 String 是不是为空,访问 String 的 isEmpty
速度最快。对于其余操作,遵从 RandomAccessCollection
协议(ContiguousArray<Int八>、String.UTF16View 以及任何
Array)的体系效用较高。

越是比较判空操作

let loopCount = 10000
var date = Date()

for _ in 0..<loopCount {
    _ = s.isEmpty
}

print("isEmpty")
printAndUpdateTime(&date)

for _ in 0..<loopCount {
    _ = s == ""
}

print("== \"\"")
printAndUpdateTime(&date)

澳门葡京备用网址 11

与走访 String 的 isEmpty 相比较,判定 String 是还是不是等于空 String
速度越来越快!

注意到文书档案中,对 String.UTF八View 和 String.UTF16View 的 Range
取下标方法的证实

subscript(bounds: Range<String.UTF8View.Index>) -> String.UTF8View { get }
subscript(bounds: Range<String.UTF16View.Index>) -> String.UTF16View { get }

Complexity: O(n) if the underlying string is bridged from Objective-C, where n is the length of the string; otherwise, O(1).

比如 String 是从 Objective-C 的 NSString 桥接来的,时间复杂度为
O(n),不然为 O(壹)。那句话怎么通晓啊?前边说了,String.UTF8View 不遵照RandomAccessCollection 协议,而 String.UTF16View 服从RandomAccessCollection
协议,两者的光阴复杂度应该例外。那里怎么说时间复杂度与 String 是还是不是桥接自
NSString 有关?以下进一步追究。

let s2 = NSString(string: s) as String

let loopCount = 10000
let index = s.characters.count / 2
let index2 = s.characters.count - 1

func test(_ s: String) {
    var date = Date()

    let utf8 = s.utf8
    for _ in 0..<loopCount {
        _ = utf8[utf8.startIndex..<utf8.index(utf8.startIndex, offsetBy: index)]
    }

    print("UTF-8 index")
    printAndUpdateTime(&date)

    for _ in 0..<loopCount {
        _ = utf8[utf8.startIndex..<utf8.index(utf8.startIndex, offsetBy: index2)]
    }

    print("UTF-8 index2")
    printAndUpdateTime(&date)

    let utf16 = s.utf16
    for _ in 0..<loopCount {
        _ = utf16[utf16.startIndex..<utf16.index(utf16.startIndex, offsetBy: index)]
    }

    print("UTF-16 index")
    printAndUpdateTime(&date)

    for _ in 0..<loopCount {
        _ = utf16[utf16.startIndex..<utf16.index(utf16.startIndex, offsetBy: index2)]
    }

    print("UTF-16 index2")
    printAndUpdateTime(&date)
}

print("String")
test(s)
print("\nString bridged from NSString")
test(s2)

测试结果

澳门葡京备用网址 12

相比较 index 与 index二 的不一致。测试参数 index二 约为 index 的 二 倍。UTF-8index二 的耗时也约为 index 的 贰 倍。UTF-1陆 的 index 和 index2耗费时间周围。那与是不是比照 RandomAccessCollection 协议一致。

比较之下 String 与 NSString 的反差。桥接自 NSString 的 String 耗费时间比 String
要长,UTF-捌 特别鲜明。那应该就是文书档案表达的情事。用 Range
取下标,桥接自 NSString 的 String,比 String 多一些操作,多出 O(n)
品级的时光
,而不是取下标的年月复杂度是 O(n)。

应用

现实应用时,接纳哪个种类编码方式、取下标方式?首先,编码格局要看现实运用场景。编码方法分裂,字符串的长度大概分化。倘若字符串只含英文,相比较好办。若是字符串含有普通话或
Emoji,选拔编码格局将要慎重。注意,NSString 的 length 属性得到的长度对应
UTF-16 编码。

let str = "abc"str.characters.count // 3str.unicodeScalars.count // 3str.utf16.count // 3(str as NSString).length // 3str.utf8.count // 3str.utf8CString.count - 1 // 3strlen(str) // 3let emojiStr = ""emojiStr.characters.count // 1emojiStr.unicodeScalars.count // 2emojiStr.utf16.count // 4(emojiStr as NSString).length // 4emojiStr.utf8.count // 8emojiStr.utf8CString.count - 1 // 8strlen(emojiStr) // 8let ChineseStr = "中文"ChineseStr.characters.count // 2ChineseStr.unicodeScalars.count // 2ChineseStr.utf16.count // 2(ChineseStr as NSString).length // 2ChineseStr.utf8.count // 6ChineseStr.utf8CString.count - 1 // 6strlen(ChineseStr) // 6

天性相比较


String、String.CharacterView、Array<Character>、String.UTF8View、Array<UInt捌>、ContiguousArray<Int八>、String.UTF16View、Array<UInt1六>
举行判空(isEmpty)、获取长度(count)、3个岗位的取下标([澳门葡京备用网址 ,index])、一段距离的取下标([range])测试,计算执行时间。

概念测试项目、打字与印刷和立异时间的办法、要测试的 String

import Foundation

enum TestType {
    case isEmpty
    case count
    case index
    case range
}

func printAndUpdateTime(_ date: inout Date) {
    let now = Date()
    print(now.timeIntervalSince(date))
    date = now
}

let s = "aasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafcpiluioufnlkqjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjliopjktyuljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasderwytwghfsdfsdfgfdsg vrutj7edbj7 fdgotuyoergcwhmkl5lknjklqawkyrcqjljkljqjlqjhbrlqwfcbhafci luioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcvcnvbwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjkn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg iopiouvrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkfghngdljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmbkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqasdfsdwkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljdqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasddfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbsdfdsrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfsadfsdgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqsdfasjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdafgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlkasdfsdfsdfgfdsg vrutj7edbj7 ergcwhmkl5lknjklqawkrcqjljkljqjlqjhbrlqwfcbhafciluioufnlkjvjakjn fnvjalgkhlkdkjlk"

测试代码

let loopCount = 10000
let index = s.characters.count / 2
let testType: TestType = .range
print(testType)
var date = Date()

forLoop: for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = s.isEmpty
    case .count:
        break forLoop
    case .index:
        _ = s[s.index(s.startIndex, offsetBy: index)]
    case .range:
        let endIndex = s.index(s.startIndex, offsetBy: index)
        _ = s[s.startIndex..<endIndex]
    }
}

if testType == .count {
    date = Date()
} else {
    print("String")
    printAndUpdateTime(&date)
}

let characters = s.characters
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = characters.isEmpty
    case .count:
        _ = characters.count
    case .index:
        _ = characters[characters.index(characters.startIndex, offsetBy: index)]
    case .range:
        let endIndex = characters.index(characters.startIndex, offsetBy: index)
        _ = characters[characters.startIndex..<endIndex]
    }
}

print("Characters")
printAndUpdateTime(&date)

let characterArr = Array(characters)
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = characterArr.isEmpty
    case .count:
        _ = characterArr.count
    case .index:
        _ = characterArr[index]
    case .range:
        _ = characterArr[0..<index]
    }
}

print("Characters array")
printAndUpdateTime(&date)

let utf8 = s.utf8
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf8.isEmpty
    case .count:
        _ = utf8.count
    case .index:
        _ = utf8[utf8.index(utf8.startIndex, offsetBy: index)]
    case .range:
        let endIndex = utf8.index(utf8.startIndex, offsetBy: index)
        _ = utf8[utf8.startIndex..<endIndex]
    }
}

print("UTF-8")
printAndUpdateTime(&date)

let utf8Arr = Array(utf8)
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf8Arr.isEmpty
    case .count:
        _ = utf8Arr.count
    case .index:
        _ = utf8Arr[index]
    case .range:
        _ = utf8Arr[0..<index]
    }
}

print("UTF-8 array")
printAndUpdateTime(&date)

let utf8CString = s.utf8CString
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf8CString.isEmpty
    case .count:
        _ = utf8CString.count
    case .index:
        _ = utf8CString[index]
    case .range:
        _ = utf8CString[0..<index]
    }
}

print("UTF-8 C string")
printAndUpdateTime(&date)

let utf16 = s.utf16
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf16.isEmpty
    case .count:
        _ = utf16.count
    case .index:
        _ = utf16[utf16.index(utf16.startIndex, offsetBy: index)]
    case .range:
        let endIndex = utf16.index(utf16.startIndex, offsetBy: index)
        _ = utf16[utf16.startIndex..<endIndex]
    }
}

print("UTF-16")
printAndUpdateTime(&date)

let utf16Arr = Array(utf16)
for _ in 0..<loopCount {
    switch testType {
    case .isEmpty:
        _ = utf16Arr.isEmpty
    case .count:
        _ = utf16Arr.count
    case .index:
        _ = utf16Arr[index]
    case .range:
        _ = utf16Arr[0..<index]
    }
}

print("UTF-16 array")
printAndUpdateTime(&date)

测试结果

判空

澳门葡京备用网址 13

收获长度

澳门葡京备用网址 14

1个职位的取下标

澳门葡京备用网址 15

壹段距离的取下标

澳门葡京备用网址 16

上述比较中,推断 String 是或不是为空,访问 String 的 isEmpty
速度最快。对于其他操作,服从 RandomAccessCollection
协议(ContiguousArray<Int八>、String.UTF1陆View 以及别的Array)的品种效用较高。

尤其相比判空操作

let loopCount = 10000
var date = Date()

for _ in 0..<loopCount {
    _ = s.isEmpty
}

print("isEmpty")
printAndUpdateTime(&date)

for _ in 0..<loopCount {
    _ = s == ""
}

print("== \"\"")
printAndUpdateTime(&date)

澳门葡京备用网址 17

与走访 String 的 isEmpty 比较,判定 String 是或不是等于空 String
速度更加快!

专注到文书档案中,对 String.UTF八View 和 String.UTF1六View 的 Range
取下标方法的认证

subscript(bounds: Range<String.UTF8View.Index>) -> String.UTF8View { get }
subscript(bounds: Range<String.UTF16View.Index>) -> String.UTF16View { get }

Complexity: O(n) if the underlying string is bridged from Objective-C, where n is the length of the string; otherwise, O(1).

万壹 String 是从 Objective-C 的 NSString 桥接来的,时间复杂度为
O(n),不然为 O(1)。那句话怎么精晓吧?后面说了,String.UTF捌View 不遵守RandomAccessCollection 协议,而 String.UTF16View 遵守RandomAccessCollection
协议,两者的时日复杂度应该例外。那里怎么说时间复杂度与 String 是或不是桥接自
NSString 有关?以下进一步搜求。

let s2 = NSString(string: s) as String

let loopCount = 10000
let index = s.characters.count / 2
let index2 = s.characters.count - 1

func test(_ s: String) {
    var date = Date()

    let utf8 = s.utf8
    for _ in 0..<loopCount {
        _ = utf8[utf8.startIndex..<utf8.index(utf8.startIndex, offsetBy: index)]
    }

    print("UTF-8 index")
    printAndUpdateTime(&date)

    for _ in 0..<loopCount {
        _ = utf8[utf8.startIndex..<utf8.index(utf8.startIndex, offsetBy: index2)]
    }

    print("UTF-8 index2")
    printAndUpdateTime(&date)

    let utf16 = s.utf16
    for _ in 0..<loopCount {
        _ = utf16[utf16.startIndex..<utf16.index(utf16.startIndex, offsetBy: index)]
    }

    print("UTF-16 index")
    printAndUpdateTime(&date)

    for _ in 0..<loopCount {
        _ = utf16[utf16.startIndex..<utf16.index(utf16.startIndex, offsetBy: index2)]
    }

    print("UTF-16 index2")
    printAndUpdateTime(&date)
}

print("String")
test(s)
print("\nString bridged from NSString")
test(s2)

测试结果

澳门葡京备用网址 18

相比 index 与 index二 的差异。测试参数 index二 约为 index 的 二 倍。UTF-八index二 的耗费时间也约为 index 的 二 倍。UTF-1陆 的 index 和 index贰耗费时间周围。那与是不是根据 RandomAccessCollection 协议1致。

对照 String 与 NSString 的异样。桥接自 NSString 的 String 耗费时间比 String
要长,UTF-八 特别举世瞩目。那应当正是文书档案表明的情况。用 Range
取下标,桥接自 NSString 的 String,比 String 多一些操作,多出 O(n)
级其他日子
,而不是取下标的时光复杂度是 O(n)。

        var fourthArray:Array<Int> = Array()

应用

切实采纳时,选择哪个种类编码格局、取下标格局?首先,编码形式要看现实运用场景。编码方法分裂,字符串的长短只怕两样。假若字符串只含英文,相比好办。假设字符串含有汉语或
Emoji,采取编码情势将要慎重。注意,NSString 的 length 属性得到的长短对应
UTF-16 编码。

let str = "abc"
str.characters.count // 3
str.unicodeScalars.count // 3
str.utf16.count // 3
(str as NSString).length // 3
str.utf8.count // 3
str.utf8CString.count - 1 // 3
strlen(str) // 3

let emojiStr = "🇵🇷"
emojiStr.characters.count // 1
emojiStr.unicodeScalars.count // 2
emojiStr.utf16.count // 4
(emojiStr as NSString).length // 4
emojiStr.utf8.count // 8
emojiStr.utf8CString.count - 1 // 8
strlen(emojiStr) // 8

let ChineseStr = "中文"
ChineseStr.characters.count // 2
ChineseStr.unicodeScalars.count // 2
ChineseStr.utf16.count // 2
(ChineseStr as NSString).length // 2
ChineseStr.utf8.count // 6
ChineseStr.utf8CString.count - 1 // 6
strlen(ChineseStr) // 6

诚如情状下,字符串要体现出来,就用
String.CharacterView。假如要取下标,思索品质,就用 String.CharacterView
生成 Array<Character>。假诺要用其余编码方式,也得以转移对应的
Array,以 Int 或 Range<Int> 取下标,效能高而且代码简洁。

近日 LeetCode 匡助 斯威夫特 了。假若做 LeetCode
的内需反复开始展览字符串取下标的主题素材,用不依据 RandomAccessCollection
协议的类型(比如String.CharacterView、String.UTF八View),大概思路对了结果却是 “Time Limit
Exceeded”。参见:

为了制止 NSString 桥接带来的质量难题,在 斯威夫特 里尽量用 String;尽量缩短Objective-C 的代码,尽量挑选 斯维夫特 编写的第3方库。

转发请注明出处:

应用

具体运用时,选择哪类编码格局、取下标格局?首先,编码情势要看现进行使场景。编码方法差异,字符串的长短恐怕两样。假设字符串只含英文,比较好办。要是字符串含有粤语或
Emoji,采取编码格局就要慎重。注意,NSString 的 length 属性获得的长短对应
UTF-1六 编码。

let str = "abc"
str.characters.count // 3
str.unicodeScalars.count // 3
str.utf16.count // 3
(str as NSString).length // 3
str.utf8.count // 3
str.utf8CString.count - 1 // 3
strlen(str) // 3

let emojiStr = "🇵🇷"
emojiStr.characters.count // 1
emojiStr.unicodeScalars.count // 2
emojiStr.utf16.count // 4
(emojiStr as NSString).length // 4
emojiStr.utf8.count // 8
emojiStr.utf8CString.count - 1 // 8
strlen(emojiStr) // 8

let ChineseStr = "中文"
ChineseStr.characters.count // 2
ChineseStr.unicodeScalars.count // 2
ChineseStr.utf16.count // 2
(ChineseStr as NSString).length // 2
ChineseStr.utf8.count // 6
ChineseStr.utf8CString.count - 1 // 6
strlen(ChineseStr) // 6

诚如情状下,字符串要展示出来,就用
String.CharacterView。若是要取下标,思虑品质,就用 String.CharacterView
生成 Array<Character>。假设要用别的编码格局,也得以转移对应的
Array,以 Int 或 Range<Int> 取下标,成效高而且代码简洁。

近来 LeetCode 帮助 斯维夫特 了。假若做 LeetCode
的急需反复展开字符串取下标的难点,用不遵从 RandomAccessCollection
协议的类型(例如String.CharacterView、String.UTF八View),可能思路对了结果却是 “Time Limit
Exceeded”。参见:

为了防止 NSString 桥接带来的性责骂题,在 Swift 里尽量用 String;尽量减少Objective-C 的代码,尽量选拔 Swift 编写的第2方库。

转发请申明出处:

        var fivethArray:Array<Int> = [Int]()

        var sixthArray:[Int] = [Int]()

        var seventhArray:[Int] = []

        var eighthArray = [1,2,3,4,5,5,6]

        var ninethArray:[Int]   //最后壹种只变动未有初试化

    2. 日增数量  append()    +      = 

        firstArray.append(250)      OC:    addObject:   

        firstArray[0] = “500”  

        firstArray += [“180″,”360″,”720″,”a”,”g”]  //加多此外1个数组

        firstArray.count

        firstArray.isEmpty

    三.  陈设成分  inset()

        firstArray.insert(“iphone6 plus”,at Index:1) 

        其余成分供给后运动,比较消耗品质

    4. 刨除元素  removeAtIndex(壹)   它的再次回到值为移除的数组成分类型

       var res: String = firstArray.removeAtIndex(1)

       res = firstArray.removeFirst()

       res = firstArray.removeLast()

       var range = Range(start:0,  end:2)

       firstArray.removeRange(Range)

   5. 更换元素

       通过下标直接改换

       shoppingList[1] = “price”

       shoppingList.removeAll()  

    6. 从数组中获得部分成分同时声惠氏个数组

       var subList = shoppingList[0..<3]   

      /**遍历*/

     for elements in subList {

        print(elements)

     }

 

    for var i = 0; i < subList.count;i++ {

        print(“第\(i)个要素是\(subList[i])”)

    }

    for (index,value) in subList.enumerate() {

        print(“第\(index) \(value)”) 

    }

    subList

   subList[0]

  1. 字典部分,成立格局

    var dictionary1:Dictionary<String,Int> =
Dictionary<String,Int>()

    var dictionary2 = Dictionary <String,Int>()

    var dictionary3:Dictionary  = Dictionary<String,Int>()

    var dictionary4:Dictionary<String,Int> = Dictionary()

    var dictionary5:Dictionary<String,Int> = [String:Int]()

    var dictionary6:Dictionary<String,Int> =
[“age”:23,”age2″:18]

    var dicitonary7 = [“age”:18,”age2″:33]

    //不能够间接选用 nil 作为变量,可是足以行使可选值座位值

    var dictionary8:[String:Int?] = [“age”:23,”age”:nil]

    //未初步化,只注明

    var dictionary9:[String:Int]

  1. 基本操作方法:

 

/**操作字典的法子*/

var airports:[String:String] = [“PEK”:”Beijing
airport”,”CAN”:”GuangzhouBaiYun airport”,”SHA”:”ShangHaiHongQiao
airport”]

airports.count

airports[“SZA”] = “Baoan airport”

//若是eky不设有正是丰裕,若是存在正是修改

airports.count

4 . updataValue( value:xxx
 ,forkey:xxx) ,注意Swift key必须写成String类型

airports.updateValue(“ShangHaiPuDong”, forKey: “PVG”)

airports.count

airports.isEmpty

airports[“TRA”] = “DaNei airport”

 

/**剔除飞机场*/

airports.count

airports[“SZA”] = nil

airports.count

 

5.删除字典成分,注意不管是去除,照旧增加进度中,都足以回去二个可选值Value

    removeValueForKey  removeAll

if let airport = airports.removeValueForKey(“TRA”){

   print(“airport: \(airport)delete successfully”)

}else {

   print(“meiyou duiying jichang”)

}

 

  1. 收获字典中持有的keys 和持有的Values,使用数组类型实行强转

    let  airportCodes = [String] (airports.keys)

    let  airportValues:[String] = [String] (airports.values)

 

//集结部分
Set,它抱有冬季性和唯1性,个人以为基本没怎么用,除了互连网并发请求外

 1. Standard style 

    var letters:Set<Character> = Set<Character>()

   
 其他写法大家自个儿雕刻去啊,之要不报错基本都行,写法太多了,和字典数组都差不离。

     其实借使保险左右两边结合起来能明确它自个儿的品种(Set,Dictionary,Array),成分类型(Int,String,Character),然后右侧必须有二个()
或然[] 就能满意须要了

 2. 增,删,交,并,差,异或

    var musics:Set<String> = [“Rock”,”Classical”,”Jazz”]

    music.isEmpty

    music.count

    music.insert(“Jazz”)

    if let removeMusic = musics.remove(“Jazz”)  {

      print (“\(removeMusic) delete successfully”)

} else {

  print(“element is not exist”)

    musics.contains(“rock”)

   for music in musics {print(music)}

   //排序

   for music  in music.sort() { print(music) }

    let oddDigits:Set = [1,3,4,5,6]

    let evemDigits:Set = [0,1,3,4,5]

    //union 并集

     var newNumbers = oddDigits.union(evenDigits)

     print(newNumbers)

    //intersect 交集

     newNumbers = oddDigits.intersect(evenDigits)

     //subtract 差集

     newNumbers = oddDigits.subtract(evenDigits)

     //异或集合,把分裂的部分提收取来

     newNumbers = oddDigits.exclusiveOr(evenDigits)

      记住好些个少个单词, uinion,intersect,subract,exclusiveOr 就好了

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website