We have a case where we're being handed an object of type Array<Any> which we need to convert to an Array<Codable>. If any of the items in the original array don't adhere to Codable, then we want the entire thing to abort and return nil.
Or current approach is to manually loop over everything, testing along the way, like so...
func makeCodable(sourceArray:Array<Any>) -> Array<Codable>?{
    var codableArray = Array<Codable>()
    for item in sourceArray{
        guard let codableItem = item as? Codable else {
            return nil
        }
        codableArray.append(codableItem)
    }
    return codableArray
}
However, I'm wondering if there's an easier way to do this with the map command, but it would require it to short-circuit if any of the elements can't be mapped.  That's what I'm not sure or not is possible.
For instance, this pseudo-code...
func makeCodable(sourceArray:Array<Any>) -> Array<Codable>?{
    return sourceArray.map({ $0 as? Codable});
}
Is this possible, or is our original way the correct/only way?
Here's one solution using map and throws.
func makeCodable(sourceArray: [Any]) -> [Codable]? {
    enum CodableError: Error {
        case notCodable
    }
    let res: [Codable]? = try? sourceArray.map {
        guard let codable = $0 as? Codable else {
            throw CodableError.notCodable
        }
        return codable
    }
    return res
}
let res = makeCodable2(sourceArray: [5, 6.5, "Hi", UIView()])
print(res) // nil
Here's a variation that makes makeCodable throw and return a non-optional array:
enum CodableError: Error {
    case notCodable
}
func makeCodable(sourceArray: [Any]) throws -> [Codable] {
    let res: [Codable] = try sourceArray.map {
        guard let cod = $0 as? Codable else {
            throw CodableError.notCodable
        }
        return cod
    }
    return res
}
do {
    let res = try makeCodable(sourceArray: [5, 6.5, "Hi"])
    print(res) // prints array
    let bad = try makeCodable(sourceArray: [5, 6.5, "Hi", UIView()])
    print(bad)
} catch {
    print(error) // goes here on 2nd call
}
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