Skip to content

Instantly share code, notes, and snippets.

@andreweades
Last active April 22, 2021 09:53
Show Gist options
  • Save andreweades/5c381caa4f8ad6584d5f9a777bb45421 to your computer and use it in GitHub Desktop.
Save andreweades/5c381caa4f8ad6584d5f9a777bb45421 to your computer and use it in GitHub Desktop.
Ways to index String with an Int.
// How to Index String by Int
// Andrew Eades
// https://www.youtube.com/channel/UC2kOJKUGXfC01YEKH4QjFRA
// Paste this into an Xcode Playground
import Cocoa
var str = "Hello, playground"
str[str.index(str.startIndex, offsetBy: 7)]
str[str.index(str.startIndex, offsetBy: 7)..<str.index(str.startIndex, offsetBy: 11)]
struct IndexableByInteger<C: RangeReplaceableCollection> {
var collection: C
init(_ collection: C) {
self.collection = collection
}
private func _index(for n: Int) -> C.Index? {
return collection.indices.dropFirst(n).first
}
subscript(intIndex: Int) -> C.Element? {
get {
guard let index = _index(for: intIndex)
else {
return nil
}
return collection[index]
}
set {
guard let index = _index(for: intIndex)
else {
return
}
var sub = C()
if let newValue = newValue {
sub.append(newValue)
}
collection.replaceSubrange(index...index, with: sub)
}
}
subscript(intRange: Range<Int>) -> C.SubSequence? {
get {
self[intRange.lowerBound ... intRange.upperBound - 1]
}
set {
self[intRange.lowerBound ... intRange.upperBound - 1] = newValue
}
}
subscript(intRange: ClosedRange<Int>) -> C.SubSequence? {
get {
guard let start = _index(for: intRange.lowerBound),
let end = _index(for: intRange.upperBound)
else {
return nil
}
return collection[start ... end]
}
set {
guard let start = _index(for: intRange.lowerBound),
let end = _index(for: intRange.upperBound)
else {
return
}
collection.replaceSubrange(start ... end, with: newValue ?? C()[...])
}
}
}
extension IndexableByInteger: CustomStringConvertible where C: CustomStringConvertible {
var description: String {
collection.description
}
}
var string = IndexableByInteger(str)
string // "Hello, plaground"
string[7] // "p"
string[7..<11] // "play"
string[0] = "Y" // "Y"
string // "Yello, playground"
string[0..<5] = "Goodbye" // "Goodbye"
string // "Goodbye, playground"
@andreweades
Copy link
Author

Removed redundant line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment