Finding index of character in Swift String -
it's time admit defeat...
in objective-c, use like:
nsstring* str = @"abcdefghi"; [str rangeofstring:@"c"].location; // 2
in swift, see similar:
var str = "abcdefghi" str.rangeofstring("c").startindex
...but gives me string.index
, can use subscript original string, not extract location from.
fwiw, string.index
has private ivar called _position
has correct value in it. don't see how it's exposed.
i know add string myself. i'm more curious i'm missing in new api.
you not 1 couldn't find solution.
string
doesn't implement randomaccessindextype
. because enable characters different byte lengths. that's why have use string.characters.count
(count
or countelements
in swift 1.x) number of characters. applies positions. _position
index raw array of bytes , don't want expose that. string.index
meant protect accessing bytes in middle of characters.
that means index must created string.startindex
or string.endindex
(string.index
implements bidirectionalindextype
). other indices can created using successor
or predecessor
methods.
now indices, there set of methods (functions in swift 1.x):
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 can index! let characterindex2 = text.characters.index(text.characters.startindex, offsetby: 2) let lastchar2 = text.characters[characterindex2] //will same 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 can index! let lastchar2 = text.characters[index2] //will same above let range: range<string.index> = text.rangeofstring("b")! let index: int = text.startindex.distanceto(range.startindex) //will call successor/predecessor several times until 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 can index! let range = text.rangeofstring("b") let index: int = distance(text.startindex, range.startindex) //will call succ/pred several times
working string.index
cumbersome using wrapper index integers (see https://stackoverflow.com/a/25152652/669586) dangerous because hides inefficiency of real indexing.
note swift indexing implementation has problem indices/ranges created 1 string cannot reliably used different string, example:
swift 2.x
let text: string = "abc" let text2: string = "πΎππ" let range = text.rangeofstring("b")! //can randomly return bad substring or throw 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 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]
Comments
Post a Comment