How to throw an error on a map to convert a string to an int array to exclude a number format

I have a line

var str = "1 2 3 4"

and I want to convert it to [Int]. This can be done as follows:

let intArray = str.characters.split {$0 == " "}.map(String.init).map { Int($0)!}

Now if my line

var invalid = " 1 a 4"

Then the program crashes with

fatal error: unexpectedly found nil while unwrapping an Optional value

I need to be able to check the number and throw a format error on the card.

+4
source share
2 answers

You can use throws, try-throw, do-try-catch and guard (if) for this. Here is the code

    var invalid = " 1 a 4"
    let intArray: [Int]
    do {
        intArray = try getIntArray(invalid, delimiter: " ")
    }catch let error as NSError {
        print(error)
        intArray = []
    }


    func getIntArray(input:String, delimiter:Character ) throws -> [Int] {
        let strArray = input.characters.split {$0 == delimiter}.map(String.init)
        let intArray = try strArray.map {
            (int:String)->Int in
            guard Int(int) != nil else {
                throw NSError.init(domain:  " \(int) is not digit", code: -99, userInfo: nil)
            }
            return Int(int)!
        }
    return intArray
    }

In the getIntArray function, we first convert the input string to a string array. Then, when we convert the string array to an int array, we expand the parameter of the card closing function to include checking the format of the number and throwing error using "guard".

"guard" "if",

    if Int(int) == nil {
        throw NSError.init(domain:  " \(int) is not digit", code: -99, userInfo: nil)
    }
+2

, NSError, Swift native enum, ErrorType, , . .

enum MyErrors : ErrorType {
    case NumberFormatError(String)
}

/* throwing function attempting to initialize an 
   integer given a string (if failure: throw error) */
func strToInt(str: String) throws -> Int {
    guard let myInt = Int(str) else { throw MyErrors.NumberFormatError(str) }
    return myInt
}

do-try-catch:

func strAsIntArr(str: String) -> [Int]? {
    var intArr: [Int] = []
    do {
        intArr = try str.characters.split {$0 == " "}
            .map(String.init)
            .map { try strToInt($0) }
    } catch MyErrors.NumberFormatError(let faultyString) {
        print("Format error: '\(faultyString)' is not number convertible.")
        // naturally you could rethrow here to propagate the error
    } catch {
        print("Unknown error.")
    }
    return intArr
}

/* successful example */
let myStringA = "1 2 3 4"
let intArrA = strAsIntArr(myStringA)
    /*[1, 2, 3, 4] */

/* error throwing example */
let myStringB = "1 b 3 4"
let intArrB = strAsIntArr(myStringB)
    /* [], Format error: 'b' is not number convertible. */
+1

All Articles