Swift: How to use for-in loop with an optional?

Swift2OptionalFor in-Loop

Swift2 Problem Overview


What's the proper way to use for-in loop with an optional?

Right now I always perform an optional binding before looping it. Are there other idioms?

let optionalInt:[Int]? = [1, 2, 3]
        
if let optionalInt = optionalInt {
  for i in optionalInt {
    print(i)
  }
}

Swift2 Solutions


Solution 1 - Swift2

If set of operations to be applied to all elements of the array, it is possible to replace for-loop with forEach{} closure and use optional chaining:

var arr: [Int]? = [1, 2, 3]
arr?.forEach{print($0)}

Solution 2 - Swift2

I don't think there's a proper way. There are many different ways, it really comes down to what you prefer, Swift is full of features that can make your program look really nice as per your choosing.

Here are some ways I could think of:

let optionalInt:[Int]? = [1, 2, 3]

for i in optionalInt! { print(i) }

for i in optionalInt ?? [] { print(i) }

for i in optionalInt as [Int]! {  print(i) }

Solution 3 - Swift2

You can write this one:

let optionalInt:[Int]? = [1, 2, 3]
for i in optionalInt ?? [Int]() {
    print(i)
}

But I'd recommend you avoid using optional value, for instance you can write like this:

var values = [Int]()
// now you may set or may not set 
for i in values {
    print(i)
}

Or if you want to use optional value and this code calls in a function can use guard:

guard let values = optionalInt else { return }
for i in values {
    print(i)
}

Solution 4 - Swift2

the cleanest solution is sometimes the most basic one

if let a = myOptionalArray {
    for i in a {
        
    }
}

so i would suggest, keep your approach

the approaches above only insert an empty option, or the forEach creates a block just because if let a = optional { isn't sexi enough

Solution 5 - Swift2

I'm two years late but I think this is the best way.

func maybe<T>(risk: T?, backup: T) -> T {
  return risk.maybe(backup)
}

and

extension Optional {
   func maybe(_ backup: Wrapped) -> Wrapped {
     switch self {
     case let .some(val):
        return val
     case .none:
        return backup
     }
   }
}

and now

for i in optionalInt.maybe([]) {
    print(i)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBoonView Question on Stackoverflow
Solution 1 - Swift2Richard TopchiiView Answer on Stackoverflow
Solution 2 - Swift2luizParreiraView Answer on Stackoverflow
Solution 3 - Swift2ArsenView Answer on Stackoverflow
Solution 4 - Swift2Peter LapisuView Answer on Stackoverflow
Solution 5 - Swift2cloudcalView Answer on Stackoverflow