Unwrapping an optional in Swift 4

1.2k Views Asked by At

I have the following code in a playground:

// Create an empty array of optional integers
var someOptionalInts = [Int?]()

// Create a function squaredSums3 with one argument, i.e. an Array of optional Ints
func squaredSums3(_ someOptionalInts: Int?...)->Int {
    // Create a variable to store the result
    var result = 0

    // Get both the index and the value (at the index) by enumerating through each element in the someOptionalInts array
    for (index, element) in someOptionalInts.enumerated() {
        // If the index of the array modulo 2 is not equal to 0, then square the element at that index and add to result
        if index % 2 != 0 {
            result += element * element
        }
    }

    // Return the result
    return result
}

// Test the code
squaredSums3(1,2,3,nil)

The line result += element * element is giving the following error "Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?" I do not want to use '!' and I have to test for the nil case. I am not sure where (or even how to be honest) to unwrap the optional. Suggestions?

4

There are 4 best solutions below

6
jancakes On BEST ANSWER

All you have to do is unwrap the optional:

if let element = element, index % 2 != 0 {
    result += element * element
}

This will ignore the nil values.

The advantage of this over any sort of mapping is that you don't have to traverse the array an extra time.

2
LinusGeffarth On

If you wanted to leave out the nil values from the array, you could compact map it:

for (index, element) in (someOptionalInts.compactMap { $0 }).enumerated() {

Then, element would not be optional anymore.


If you instead wanted to treat all nil values as 0, then you could do:

if index % 2 != 0 {
    result += (element ?? 0) * (element ?? 0)
}
1
zheck On

The error appears because you have to specify what to do in case element is nil

if index % 2 != 0 {
    if let element = element {
        result += element * element
    }
    else {
        // do whatever you want
    }
}
0
Code Different On

Here's how I would write it:

for (index, element) in someOptionalInts.enumerated() {
    guard let element = element, index % 2 == 0 else { continue }
    result += element * element
}
// result == 10

The guard statement means that I'm only interested when element is not nil and its index is even.