Last active
January 29, 2019 21:39
-
-
Save milseman/b73a4b07dcf613703cb72363bf377673 to your computer and use it in GitHub Desktop.
String Index Explicit Offsets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension String.Index { | |
/// Creates a new index at the specified UTF-16 code unit offset | |
/// | |
/// - Parameter offset: An offset in UTF-16 code units. | |
public init(offset: Int, within utf16: String.UTF16View) { | |
let (start, end) = (utf16.startIndex, utf16.endIndex) | |
guard offset >= 0, | |
let idx = utf16.index(start, offsetBy: offset, limitedBy: end) | |
else { | |
self = end | |
return | |
} | |
self = idx | |
} | |
/// Creates a new index at the specified UTF-8 code unit offset | |
/// | |
/// - Parameter offset: An offset in UTF-8 code units. | |
public init(offset: Int, within utf8: String.UTF8View) { | |
let (start, end) = (utf8.startIndex, utf8.endIndex) | |
guard offset >= 0, | |
let idx = utf8.index(start, offsetBy: offset, limitedBy: end) | |
else { | |
self = end | |
return | |
} | |
self = idx | |
} | |
/// Creates a new index at the specified Unicode scalar offset | |
/// | |
/// - Parameter offset: An offset in terms of Unicode scalar values | |
public init(offset: Int, within scalars: String.UnicodeScalarView) { | |
let (start, end) = (scalars.startIndex, scalars.endIndex) | |
guard offset >= 0, | |
let idx = scalars.index(start, offsetBy: offset, limitedBy: end) | |
else { | |
self = end | |
return | |
} | |
self = idx | |
} | |
/// Creates a new index at the specified Character offset | |
/// | |
/// - Parameter offset: An offset in terms of Characters | |
public init(offset: Int, within str: String) { | |
let (start, end) = (str.startIndex, str.endIndex) | |
guard offset >= 0, | |
let idx = str.index(start, offsetBy: offset, limitedBy: end) | |
else { | |
self = end | |
return | |
} | |
self = idx | |
} | |
/// The UTF-16 code unit offset corresponding to this Index | |
public func offset(within utf16: String.UTF16View) -> Int { | |
return utf16.distance(from: utf16.startIndex, to: self) | |
} | |
/// The UTF-8 code unit offset corresponding to this Index | |
public func offset(within utf8: String.UTF8View) -> Int { | |
return utf8.distance(from: utf8.startIndex, to: self) | |
} | |
/// The Unicode scalar offset corresponding to this Index | |
public func offset(within scalars: String.UnicodeScalarView) -> Int { | |
return scalars.distance(from: scalars.startIndex, to: self) | |
} | |
/// The Character offset corresponding to this Index | |
public func offset(within str: String) -> Int { | |
return str.distance(from: str.startIndex, to: self) | |
} | |
} | |
let myString = "abcde\u{301}γγγππΆ" | |
for index in myString.indices { | |
print("Character offset: \(index.offset(within: myString))") | |
} | |
for index in myString.utf8.indices { | |
print("UTF-8 offset: \(index.offset(within: myString.utf8))") | |
} | |
for index in myString.utf16.indices { | |
print("UTF-16 offset: \(index.offset(within: myString.utf16))") | |
} | |
for index in myString.unicodeScalars.indices { | |
print("Scalar offset: \(index.offset(within: myString.unicodeScalars))") | |
} | |
print("UTF-8") | |
for i in 0..<myString.utf8.count { | |
print(myString.utf8[String.Index(offset: i, within: myString.utf8)]) | |
} | |
print("UTF-16") | |
for i in 0..<myString.utf16.count { | |
print(myString.utf16[String.Index(offset: i, within: myString.utf16)]) | |
} | |
print("Scalars") | |
for i in 0..<myString.unicodeScalars.count { | |
print(myString.unicodeScalars[String.Index(offset: i, within: myString.unicodeScalars)]) | |
} | |
print("Characters") | |
for i in 0..<myString.count { | |
print(myString[String.Index(offset: i, within: myString)]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment