Skip to content

Instantly share code, notes, and snippets.

@dduan
Created August 12, 2016 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dduan/099fbf07678091e8880fffcd49cf36e9 to your computer and use it in GitHub Desktop.
Save dduan/099fbf07678091e8880fffcd49cf36e9 to your computer and use it in GitHub Desktop.
An array that's never empty.
enum OneArray<T> {
case one(T)
case many([T])
// Want empty value? Fuck you.
init?<S: Sequence where S.Iterator.Element == T>(_ s: S) {
switch s.underestimatedCount {
case 0:
return nil
case 1:
self = .one(s.first(where: { _ in true })!)
default:
self = .many(Array(s))
}
}
// Use it like a normal array. TODO: conform to Collection
subscript(_ index: Int) -> T {
get {
switch self {
case .one(let value):
return value
case .many(let values):
return values[index]
}
}
set(newValue) {
switch (self, index) {
case (.one, 0):
self = .one(newValue)
case (.one, _):
break
case (.many(let values), _):
var newValues = values
newValues[index] = newValue
self = .many(newValues)
}
}
}
var count: Int {
switch self {
case .one:
return 1
case .many(let values):
return values.count
}
}
// .first and .last are not optional, NICE.
var first: T {
switch self {
case .one(let value):
return value
case .many(let values):
return values.first!
}
}
var last: T {
switch self {
case .one(let value):
return value
case .many(let values):
return values.last!
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment