Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An rudimentary experiment on Swift slice syntax.
// Experimental:
// '%' replaces the more ideal '$'
// where a open ended range is in the design, `nil` is used its place
// force casting between Index.Distance and 'Int'
// only on CollectionType, but a version for string is not hard to do
public struct Offset { let value: Int }
prefix operator %+ {}
prefix operator %- {}
prefix func %+(offset: Int) -> Offset {
return Offset(value: offset)
}
prefix func %-(offset: Int) -> Offset {
return Offset(value: -offset)
}
internal func normalize(start: Int?, end: Int?, total: Int) -> (Int, Int) {
var actualStart = start ?? 0
var actualEnd = end ?? total
actualStart = actualStart < 0 ? total + actualStart : actualStart
actualEnd = actualEnd < 0 ? total + actualEnd : actualEnd
// uncomment the following for a much more forgiving implementation
// actualStart = actualStart < 0 ? 0 : actualStart
// actualEnd = actualEnd < 0 ? 0 : actualEnd
// let safeEnd = min(actualEnd, total)
// return (min(actualStart, safeEnd), safeEnd)
return (actualStart, actualEnd)
}
extension CollectionType {
public subscript(start:Offset?, end:Offset?) -> Self.SubSequence {
let (safeStart, safeEnd) = normalize(
start?.value, end: end?.value, total: self.count as! Int)
let safeStartIndex = startIndex.advancedBy(safeStart as! Self.Index.Distance)
let safeEndIndex = startIndex.advancedBy(safeEnd as! Self.Index.Distance)
return self[safeStartIndex..<safeEndIndex]
}
public subscript(index: Offset) -> Self.Generator.Element {
let (safeStart, _) = normalize(
index.value, end: 0, total: self.count as! Int)
return self[startIndex.advancedBy(safeStart as! Self.Index.Distance)]
}
}
let s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// equavelent in Swift Python Result
s[%+2] // s[s.startIndex.advancedBy(2)] s[2] 2
s[%-2] // s[s.endIndex.advancedBy(-2)] s[-2] 8
s[%+2, %-3] // s.dropFirst(2).dropLast(3) s[2:-2] [2, 3, 4, 5, 6]
s[%-5, nil] // s.dropFirst(s.count - 5) s[-5:] [5, 6, 7, 8, 9]
s[nil, %-8] // s.dropLast(8) s[:-8] [0, 1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.