Swift Conditional Conformance with Any

后端 未结 2 1157
小鲜肉
小鲜肉 2021-01-27 05:03

Let\'s assume an array of Result. We want the array to be reduced to a Result of an array. For example:

let z: [Result         


        
2条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-27 05:20

    You can create a generic method and remove the constraint from the extension:

    extension Sequence {
        func reduced() -> Result<[T], Error> where Element == Result {
            reduce(.success([])) {
                switch $0 {
                case .failure: return $0
                case let .success(array):
                    switch $1 {
                    case let .failure(error): return .failure(error)
                    case let .success(value): return .success(array + CollectionOfOne(value))
                    }
                }
            }
        }
    }
    

    Btw you can also use a plain loop and provide an early exit at the first failure:

    extension Sequence {
        func reduced() -> Result<[T], Error> where Element == Result {
            var array: [T] = []
            for result in self {
                switch result {
                case let .failure(error): return .failure(error)
                case let .success(value): array.append(value)
                }
            }
            return .success(array)
        }
    }
    

    A more concise approach would be to create a generic method that throws or return an array with all successes:

    extension Sequence {
        func successes() throws -> [T] where Element == Result, E: Error {
            try map { try $0.get() }
        }
    }
    

    Playground testing:

    let z: [Result] = [.success(1),
                                   .success(2),
                                   .success(3)] //,
                                   //.failure(.blah)]
    do {
        let successes = try z.successes()
        print(successes)  // [1, 2, 3]
    } catch {
        print(error)
    }
    

提交回复
热议问题