-
-
Save kemchenj/882e064d2a881cfe62ac0df170a60648 to your computer and use it in GitHub Desktop.
字符串的下标取值语法糖
This file contains 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
import Foundation | |
let str = """ | |
床前明月光,疑是地上霜。 | |
举头望明月,低头思故乡。 | |
""" | |
str[3...] | |
str[...3] | |
str[..<3] | |
str[3...11] | |
str[(-11)...] | |
str[...(-11)] |
This file contains 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
import Foundation | |
fileprivate | |
extension String { | |
func validIndex(original: Int) -> String.Index { | |
switch original { | |
case ...startIndex.encodedOffset : return startIndex | |
case endIndex.encodedOffset... : return endIndex | |
default : return index(startIndex, offsetBy: original) | |
} | |
} | |
func validStartIndex(original: Int) -> String.Index? { | |
guard original <= endIndex.encodedOffset else { return nil } | |
return validIndex(original:original) | |
} | |
func validEndIndex(original: Int) -> String.Index? { | |
guard original >= startIndex.encodedOffset else { return nil } | |
return validIndex(original:original) | |
} | |
} | |
public | |
extension String { | |
subscript(_ range: Range<Int>) -> String { | |
guard | |
let startIndex = validStartIndex(original: range.lowerBound), | |
let endIndex = validEndIndex(original: range.upperBound), | |
startIndex < endIndex | |
else { | |
return "" | |
} | |
return String(self[startIndex..<endIndex]) | |
} | |
subscript(_ range: CountableRange<Int>) -> String { | |
guard | |
let startIndex = validStartIndex(original: range.lowerBound), | |
let endIndex = validEndIndex(original: range.upperBound), | |
startIndex < endIndex | |
else { | |
return "" | |
} | |
return String(self[startIndex..<endIndex]) | |
} | |
subscript(_ range: ClosedRange<Int>) -> String { | |
guard | |
let startIndex = validStartIndex(original: range.lowerBound), | |
let endIndex = validEndIndex(original: range.upperBound) | |
else { | |
return "" | |
} | |
return String(self[startIndex...endIndex]) | |
} | |
subscript(_ range: CountableClosedRange<Int>) -> String { | |
guard | |
let startIndex = validStartIndex(original: range.lowerBound), | |
let endIndex = validEndIndex(original: range.upperBound) | |
else { | |
return "" | |
} | |
return String(self[startIndex...endIndex]) | |
} | |
subscript(_ range: PartialRangeFrom<Int>) -> String { | |
guard let startIndex = validStartIndex(original: range.lowerBound) else { | |
return "" | |
} | |
return String(self[startIndex...]) | |
} | |
subscript(_ range: CountablePartialRangeFrom<Int>) -> String { | |
guard let startIndex = validStartIndex(original: range.lowerBound) else { | |
return "" | |
} | |
return String(self[startIndex...]) | |
} | |
subscript(_ range: PartialRangeThrough<Int>) -> String { | |
guard let endIndex = validEndIndex(original: range.upperBound) else { | |
return "" | |
} | |
return String(self[...endIndex]) | |
} | |
subscript(_ range: PartialRangeUpTo<Int>) -> String { | |
guard | |
let endIndex = validEndIndex(original: range.upperBound), | |
endIndex > startIndex | |
else { | |
return "" | |
} | |
return String(self[..<endIndex]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment