Here is what I'm trying to do:
extension Array<Optional<T>> {   
  func unwrap() -> Optional<Array<T>> {
    let a = self.flatMap() { a in
      switch a {
      case Optional.Some(let x): return [x]
      case Optional.None: return []
      }
    }
    if a.count == self.count {
      return Optional.Some(a)
    } else {
      return Optional.None
    }   
  } 
}
But, it doesn't compiles with error Use of undeclared type T.
Here is how I want to use it:
let a = [Optional.Some(2), Optional.Some(3), Optional.Some(4)]
let b = [Optional.Some(1), Optional.None]
a.unwrap() // Optional[2, 3, 4]
b.unwrap() // nil
How can I get around with this? Or there is no such possibility in swift?
Try this:
protocol OptionalType {
    typealias W
    var optional: W? { get }
}
extension Optional: OptionalType {
    typealias W = Wrapped
    var optional: W? { return self }
}
extension Array where Element: OptionalType {
    func unwrap() -> [Element.W]? {
        return reduce(Optional<[Element.W]>([])) { acc, e in
            acc.flatMap { a in e.optional.map { a + [$0] } }
        }
    } 
}
And then,
let a: [Int?] = [1,   2, 3]
let b: [Int?] = [1, nil, 3]
a.unwrap() // ==> [1, 2, 3]
b.unwrap() // ==> nil
                        Inspired by the solution by @findall, this works with Swift 4:
protocol OptionalType {
    associatedtype Wrapped
    var optional: Wrapped? { get }
}
extension Optional: OptionalType {
    var optional: Wrapped? { return self }
}
extension Sequence where Iterator.Element: OptionalType {
    func removeNils() -> [Iterator.Element.Wrapped] {
        return self.flatMap { $0.optional }
    }
}
class UtilitiesTests: XCTestCase {
    
    func testRemoveNils() {
        let optionalString: String? = nil
        let strings: [String?] = ["Foo", optionalString, "Bar", optionalString, "Baz"]
        XCTAssert(strings.count == 5)
        XCTAssert(strings.removeNils().count == 3)
        let integers: [Int?] = [2, nil, 4, nil, nil, 5]
        XCTAssert(integers.count == 6)
        XCTAssert(integers.removeNils().count == 3)
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With