Anda bukan satu-satunya yang tidak dapat menemukan solusinya.
String
tidak menerapkan RandomAccessIndexType
. Mungkin karena mereka mengaktifkan karakter dengan panjang byte yang berbeda. Itu sebabnya kita harus menggunakan string.characters.count
( count
atau countElements
dalam Swift 1.x) untuk mendapatkan jumlah karakter. Itu juga berlaku untuk posisi. The _position
mungkin indeks ke dalam array mentah byte dan mereka tidak ingin mengekspos itu. Ini String.Index
dimaksudkan untuk melindungi kita dari mengakses byte di tengah karakter.
Itu berarti bahwa indeks apa pun yang Anda dapatkan harus dibuat dari String.startIndex
atau String.endIndex
( String.Index
mengimplementasikan BidirectionalIndexType
). Indeks lainnya dapat dibuat menggunakan successor
atau predecessor
metode.
Sekarang untuk membantu kami dengan indeks, ada satu set metode (fungsi di Swift 1.x):
Swift 4.x
let text = "abc"
let index2 = text.index(text.startIndex, offsetBy: 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let characterIndex2 = text.index(text.startIndex, offsetBy: 2)
let lastChar2 = text[characterIndex2] //will do the same as above
let range: Range<String.Index> = text.range(of: "b")!
let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)
Swift 3.0
let text = "abc"
let index2 = text.index(text.startIndex, offsetBy: 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let characterIndex2 = text.characters.index(text.characters.startIndex, offsetBy: 2)
let lastChar2 = text.characters[characterIndex2] //will do the same as above
let range: Range<String.Index> = text.range(of: "b")!
let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)
Swift 2.x
let text = "abc"
let index2 = text.startIndex.advancedBy(2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let lastChar2 = text.characters[index2] //will do the same as above
let range: Range<String.Index> = text.rangeOfString("b")!
let index: Int = text.startIndex.distanceTo(range.startIndex) //will call successor/predecessor several times until the indices match
Swift 1.x
let text = "abc"
let index2 = advance(text.startIndex, 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let range = text.rangeOfString("b")
let index: Int = distance(text.startIndex, range.startIndex) //will call succ/pred several times
Bekerja dengan String.Index
itu rumit tetapi menggunakan pembungkus untuk mengindeks oleh bilangan bulat (lihat https://stackoverflow.com/a/25152652/669586 ) berbahaya karena menyembunyikan inefisiensi pengindeksan nyata.
Perhatikan bahwa implementasi pengindeksan Swift memiliki masalah yang indeks / rentang yang dibuat untuk satu string tidak dapat diandalkan digunakan untuk string yang berbeda , misalnya:
Swift 2.x
let text: String = "abc"
let text2: String = "πΎππ"
let range = text.rangeOfString("b")!
//can randomly return a bad substring or throw an exception
let substring: String = text2[range]
//the correct solution
let intIndex: Int = text.startIndex.distanceTo(range.startIndex)
let startIndex2 = text2.startIndex.advancedBy(intIndex)
let range2 = startIndex2...startIndex2
let substring: String = text2[range2]
Swift 1.x
let text: String = "abc"
let text2: String = "πΎππ"
let range = text.rangeOfString("b")
//can randomly return nil or a bad substring
let substring: String = text2[range]
//the correct solution
let intIndex: Int = distance(text.startIndex, range.startIndex)
let startIndex2 = advance(text2.startIndex, intIndex)
let range2 = startIndex2...startIndex2
let substring: String = text2[range2]