Skip to content

Instantly share code, notes, and snippets.

@jamesujeon
Last active November 4, 2021 11:14
Show Gist options
  • Save jamesujeon/3f3db1aefc51c4251acb07c5b1af6991 to your computer and use it in GitHub Desktop.
Save jamesujeon/3f3db1aefc51c4251acb07c5b1af6991 to your computer and use it in GitHub Desktop.
Subscript `Collection` safely with `Optional`
import Foundation
extension Collection {
subscript(safe index: Index) -> Element? {
indices.contains(index) ? self[index] : nil
}
subscript(safe range: Range<Index>) -> SubSequence? {
indices.contains(range.lowerBound) && indices.contains(range.upperBound) ? self[range] : nil
}
subscript(safe range: ClosedRange<Index>) -> SubSequence? {
indices.contains(range.lowerBound) && indices.contains(range.upperBound) ? self[range] : nil
}
subscript(safe range: PartialRangeUpTo<Index>) -> SubSequence? {
indices.contains(range.upperBound) ? self[range] : nil
}
subscript(safe range: PartialRangeThrough<Index>) -> SubSequence? {
indices.contains(range.upperBound) ? self[range] : nil
}
subscript(safe range: PartialRangeFrom<Index>) -> SubSequence? {
indices.contains(range.lowerBound) ? self[range] : nil
}
}
extension MutableCollection {
subscript(safe index: Index) -> Element? {
get {
indices.contains(index) ? self[index] : nil
}
set {
guard let newValue = newValue,
indices.contains(index)
else { return }
self[index] = newValue
}
}
subscript(safe range: Range<Index>) -> SubSequence? {
get {
indices.contains(range.lowerBound) && indices.contains(range.upperBound) ? self[range] : nil
}
set {
guard let newValue = newValue,
indices.contains(range.lowerBound),
indices.contains(range.upperBound)
else { return }
self[range] = newValue
}
}
subscript(safe range: ClosedRange<Index>) -> SubSequence? {
get {
indices.contains(range.lowerBound) && indices.contains(range.upperBound) ? self[range] : nil
}
set {
guard let newValue = newValue,
indices.contains(range.lowerBound),
indices.contains(range.upperBound)
else { return }
self[range] = newValue
}
}
subscript(safe range: PartialRangeUpTo<Index>) -> SubSequence? {
get {
indices.contains(range.upperBound) ? self[range] : nil
}
set {
guard let newValue = newValue,
indices.contains(range.upperBound)
else { return }
self[range] = newValue
}
}
subscript(safe range: PartialRangeThrough<Index>) -> SubSequence? {
get {
indices.contains(range.upperBound) ? self[range] : nil
}
set {
guard let newValue = newValue,
indices.contains(range.upperBound)
else { return }
self[range] = newValue
}
}
subscript(safe range: PartialRangeFrom<Index>) -> SubSequence? {
get {
indices.contains(range.lowerBound) ? self[range] : nil
}
set {
guard let newValue = newValue,
indices.contains(range.lowerBound)
else { return }
self[range] = newValue
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment