函数数组<optional <t>&gt; - &GT;可选的<阵列<T>&GT;

时间:2015-10-15 02:15:57

标签: arrays swift generics swift2 optional

这是我正在尝试做的事情:

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
    }   
  } 
}

但是,它不会编译错误Use of undeclared type T。 以下是我想要使用它的方法:

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

我怎样才能解决这个问题?或者在swift中没有这种可能性?

3 个答案:

答案 0 :(得分:7)

试试这个:

head

然后,

head_lock

答案 1 :(得分:3)

Swift 4

受@findall解决方案的启发,这适用于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)
    }
}

答案 2 :(得分:-1)

findall的解决方案可行,但我认为在这种情况下避免使用泛型更具可读性:

func unwrap<Element>(optionalArray : [Element?]) -> [Element]? {
    let unwrappedArray = optionalArray.flatMap { (a) -> [Element] in
        switch a {
        case Optional.Some(let x): return [x]
        case Optional.None: return []
        }
    }

    return unwrappedArray.count == optionalArray.count ? Optional.Some(unwrappedArray) : Optional.None
}

用法:

let a = [Optional.Some(2), Optional.Some(3), Optional.Some(4)]
let b = [Optional.Some(1), Optional.None]

// Both are [Int]?
let unwrappedA = unwrap(a) // [2, 3, 4]
let unwrappedB = unwrap(b) // nil

另请参阅:How to determine if a generic is an optional in Swift?