I think the canonical name for this operation is unzip?
I was hoping this would work, but it crashes the compiler.
func unzip<each T>(_ tuple: (repeat each T)?) -> (repeat (each T)?) {
tuple ?? (repeat nil as (each T)?)
}
You can work around it with this, though:
func unzip<each T>(_ tuple: (repeat each T)?) -> (repeat (each T)?) {
tuple.map { (repeat each $0) } ?? (repeat nil as (each T)?)
}
Unfortunately, the same trick doesn't work on a method, which this probably should be*.
Crashes:
extension Optional {
func unzip<each WrappedElement >() -> (repeat (each WrappedElement)?)
where Wrapped == (repeat each WrappedElement) {
map { (repeat each $0) } ?? (repeat nil as (each WrappedElement)?)
}
}
Workaround:
extension Optional {
func unzip<each WrappedElement>() -> (repeat (each WrappedElement)?)
where Wrapped == (repeat each WrappedElement) {
switch self {
case let wrapped?: (repeat each wrapped)
case nil: (repeat nil as (each WrappedElement)?)
}
}
}
* Ha! Maybe stick with that global function until post-beta season, when there might be some time for people to work on this…
↔
let two: Optional = (1, 2)
unzip(two)
two.unzip()
let one: Optional = 1
unzip(one)
one.unzip() // runtime crash