[Swift]Day02:Swift 中的字串,swiftday02字串
簡介
String
中的字串是實值型別,傳遞的時候會對值進行拷貝,而 NSString
的字串傳遞則是引用。我們可以用 for in
遍曆字串:
var a : String = “a”for c in “Hello” { println(c)}
可以通過 countElements
計算字串的字元數量:
countElements(“1234567”) // 7
不過要注意的是,countElements
和 NSString 的 length
並不總是完全一樣的值,因為length
利用的是 UTF-16 類型的值,而不是 Unicode 字元。比如 emoji 表情加進去之後,UTF-16 算的結果是2,而 Unicode 的計算結果是1。可以看下面這個例子:
var a = “Hello”countElements(a) // 6 - Unicodea.utf16Count // 7 - UTF16
可以用 utf8 擷取 utf-8 的表示,同樣,可以用 utf16 擷取 utf-16 的表示:
var b = “Hello”// 72 101 108 108 111 240 159 144 182for c in b.utf8 { println(c)}// 72 101 108 108 111 55357 56374for c in b.utf16 { println(c)}
如果要擷取 Unicode 標量可以用 unicodeScalars
來擷取:
// 68 111 103 33 128054”for scalar in b.unicodeScalars { print(“\(scalar.value) “)}
子串
我們沒有辦法直接用 str[0...4]
來截取子串,因為 String 的 Subscript
的參數必須是String.Index
的:
subscript(i: String.Index) -> Character { get }subscript(subRange: Range<String.Index>) -> String { get }
要擷取 SubString 的話需要這樣:
let digits = “0123456789”let position = 3let index = advance(digits.startIndex, position)let character = digits[index] // -> “3”
或者用 substringWithRange
方法:
var str = “abcdefg”str.substringWithRange(Range<String.Index>(start: advance(str.startIndex,2), end: str.endIndex))
其中, advance(i, n)
等價於 i++n
,只需要傳一個 ForwardIndexType
的值,就可以返回 i
往後的第 n
個值。比如 advance(1, 2)
返回的是 1+2
也就是3。
我們可以通過 Extension
的方式給 String 加上整數類型的下標:
var digits = “12345678901234567890”extension String{ subscript(integerIndex: Int) -> Character { let index = advance(startIndex, integerIndex) return self[index] } subscript(integerRange: Range<Int>) -> String { let start = advance(startIndex, integerRange.startIndex) let end = advance(startIndex, integerRange.endIndex) let range = start..<end return self[range] }}digits[5] // works nowdigits[4…6] // works now
可以用 rangeOfString()
來判斷是否包含子串:
var myString = “Swift is really easy!”if myString.rangeOfString(“easy”) != nil { println(“Exists!”)}
拼接
把數組裡的值拼接成字串是經常遇到的情況。我們可以用遍曆拼接所有元素:
let animals = [“cat”, “dog”, “turtle”, “swift”, “elephant”]var result: String = “”for animal in animals { if countElements(result) > 0 { result += “,” } result += animal}result // “cat,dog,turtle,swift,elephant”
當然也有更簡單的方式,join
函數:
println(“a list of animals: ” + “,”.join(animals))
可以用 map
給每個元素都加個列表標記:
println(“\n”.join(animals.map({ “- ” + $0})))
可以用 capitalizedString 將字串首字母大寫:
let capitalizedAnimals = animals.map({ $0.capitalizedString })println(“\n”.join(capitalizedAnimals.map({ “- ” + $0})))
可以通過 sorted()
方法對數組內的元素進行排序:
let sortedAnimals = animals.sorted({ (first, second) -> Bool in return first < second})println(“\n”.join(sortedAnimals.map({ “- ” + $0})))
你可以通過自訂運算子的方式來實現字串 *n
的效果,就像是 3*5=15
這樣:
func *(string: String, scalar: Int) -> String { let array = Array(count: scalar, repeatedValue: string) return “”.join(array)}println(“cat ” * 3 + “dog ” * 2)// cat cat cat dog dog
分解
基於 Foundation
,我們可以用 componentsSeparatedByString
把字串分解成數組:
import Foundationvar myString = “Berlin, Paris, New York, San Francisco”var myArray = myString.componentsSeparatedByString(“,”)//Returns an array with the following values: [“Berlin”, ” Paris”, ” New York”, ” San Francisco”]
如果你希望基於多個字元進行分解,那需要使用另一個方法:
import Foundationvar myString = “One-Two-Three-1 2 3”var array : [String] = myString.componentsSeparatedByCharactersInSet(NSCharacterSet (charactersInString: “- “))//Returns [“One”, “Two”, “Three”, “1”, “2”, “3”]
如果不希望基於 Foundation
進行分解,可以使用全域函數 split()
:
var str = “Today is so hot”let arr = split(str, { $0 == ” “}, maxSplit: Int.max, allowEmptySlices: false)println(arr) // [Today, is, so, hot]
總結
在 Swift 中,String
和 NSString
會自動轉換。雖然 String 已經很強大,但是用起來總歸不太順手。可以參考一下網上的 ExSwift 項目,其中的 String.swift 很好的補充了一些 String 中常用而 Apple 又沒有提供的內容。
References
- Playing with Strings
- String reference guide for Swift
- Swift version of componentsSeparatedByString
- Strings in Swift