Çözümü bulamayan tek kişi sen değilsin.
Stringuygulanmaz RandomAccessIndexType. Muhtemelen farklı bayt uzunluklarına sahip karakterleri etkinleştirdikleri için. Bu yüzden karakter sayısını elde etmek için kullanmalıyız string.characters.count( countveya countElementsSwift 1.x'te). Bu durum pozisyonlar için de geçerlidir. _positionMuhtemelen bayt ham diziye bir endeksidir ve onlar maruz istemiyorum. Bu String.Index, bizi karakterlerin ortasında baytlara erişmekten korumak içindir.
Bu, aldığınız herhangi bir dizinin String.startIndexveya String.endIndex( String.Indexuygular BidirectionalIndexType) dizininden oluşturulması gerektiği anlamına gelir . Diğer indeksler successorveya predecessoryöntemler kullanılarak oluşturulabilir .
Şimdi endekslerde bize yardımcı olmak için bir dizi yöntem var (Swift 1.x'teki fonksiyonlar):
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
Gerçek endekslemenin verimsizliğini gizlediği için birlikte çalışmak String.Indexhantaldır, ancak tamsayılarla dizin oluşturmak için bir sarıcı kullanmak (bkz. Https://stackoverflow.com/a/25152652/669586 ) tehlikelidir.
Swift dizin oluşturma uygulamasında, bir dize için oluşturulan dizinlerin / aralıkların farklı bir dize için güvenilir bir şekilde kullanılamadığı sorunu olduğunu unutmayın, örneğin:
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]