Workflow statements

if

The if statement allows to execute code based on the evaluation of one or more conditions.

else if is optional block. Also can be several else if blocks.

if boolean_expr1 {
    // ...
} else if boolean_expr2 { 
    // ...
} else {
    // ...
}

The let clause unwrap an optional value into a non-optional variable that exists only in the if let scope.

// without if let
let myObj = newObj(param)

if myObj != nil {
    print("object created")
} else {
    print("object not created")
}

// with if let
if let myObj = newObj(param) {
    print("object created")
}else{
    print("object created")
    // myObj not accessible here
}

You can unwrap multiple values or specify additional condition after unwrapping.

if let a = optA, let b = optB, let c = optC {
    // executed if all the assignments are properly completed
}

if let a = optInt, a<10 {
    // executed if all the assignments are properly completed
}

guard

The guard statement is "reverse" version of if statement. In other words, the guard block will be executed if the condition is false.

if name.characters.count <= 0 {
    throw InputError.NameIsEmpty
} // with if statement we specify unwanted condition 


guard name.characters.count > 0 else {
    throw InputError.NameIsEmpty
}// with guard statement we specify wanted condition

guard #available(iOS 9, *) else {
    return
}

Any optional variables unwrapped by guard remain in scope after the guard finishes, so you can use them. It is different from if.

guard let myString = getString() else {
    // ... do something
    return
}

print(myString)

The where clause allows to test additional condition, when initial condition is true.

guard let name = pswField.text where psw.characters.count > 7 else {
    print("password must be at least 8 characters long")
    return
}

switch

Switch statement support tuple and range values.

Unlike C case statement must have body, otherwise you will get a compile-time error.

switch some_value_to_consider {
    case value_1:
        // .. respond to value 1
    case value_2,
         value_3:
        // ... respond to value 2 or 3
    default:
        // do something else
    }
let somePoint = (1, 1)

switch somePoint {
case (0, 0):
    print("\(somePoint) is at the origin")
case (_, 0):
    print("\(somePoint) is on the x-axis")
case (0, _):
    print("\(somePoint) is on the y-axis")
case (-2...2, -2...2):
    print("\(somePoint) is inside the box")
default:
    print("\(somePoint) is outside of the box")
}
let approximateCount = 62
let countedThings = "moons orbiting Saturn"
let naturalCount: String

switch approximateCount {
    case 0:
        naturalCount = "no"
    case 1..<5:
        naturalCount = "a few"
    case 5..<12:
        naturalCount = "several"
    case 12..<100:
        naturalCount = "dozens of"
    case 100..<1000:
        naturalCount = "hundreds of"
    default:
        naturalCount = "many"
}

print("There are \(naturalCount) \(countedThings).")
// Prints "There are dozens of moons orbiting Saturn."
switch some_value_to_consider {
    case value_1:
        // .. respond to value 1
    case value_2
    case value_3:
        // ... respond to value 2 or 3
    default:
        // do something else
    }
// compile-time error    

A switch case can use a where clause to check for additional conditions.

let yetAnotherPoint = (1, -1)

switch yetAnotherPoint {
    case let (x, y) where x == y:
        print("(\(x), \(y)) is on the line x == y")
    case let (x, y) where x == -y:
        print("(\(x), \(y)) is on the line x == -y")
    case let (x, y):
        print("(\(x), \(y)) is just some arbitrary point")
}
// Prints "(1, -1) is on the line x == -y"

for in

for-in loop iterates over a sequence, such as items in an array, ranges of numbers, or characters in a string.

stride() functions can be used to create ranges.

var names = ["Anna", "Alex", "Brian", "Jack"]
// iterate over value, same as names.forEach { print("Hello, \($0)!")  }
for name in names {
    print("Hello, \(name)!")
}

// iterate over index and value
for (index, name) in names.enumerated() {
    print("\(name) at index:\(index)")    
}

// iterate over index and value with condition
for (index, name) in names.enumerated() where name == "Brian" {
                names.remove(at: index)
}

let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)s have \(legCount) legs")
}
for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}

let base = 3
let power = 10
var answer = 1
for _ in 1...power {
    answer *= base
}

let minutes = 60
for tickMark in 0..<minutes {
    // tickMark: 0,1,..., 59
}

let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
    // tickMark: 0, 5, 10, 15 ... 45, 50, 55
}

let hours = 12
let hourInterval = 3
for tickMark in stride(from: 3, through: hours, by: hourInterval) {
    // tickMark: 3, 6, 9, 12
}
let str = "Hello world"
for char in str {
    print("Found character: \(char)")
}

while

A while loop starts by evaluating a single condition. If the condition is true, a set of statements is repeated until the condition becomes false.

// while condition {
//    statements
//}

var i = 1, n = 5

while (i <= n) {
  print(i)
   i = i + 1
}

repeat-while

The repeat-while loop executes the body and then checks the condition. If it's satisfies, the loop repeats.

// repeat {
//    statements
// } while (condition)

var i = 1, n = 5

repeat {
  
  print(i)
  i = i + 1
  
} while (i <= n)

break

The break statement allows to terminate the nearest enclosing loop or exit from switch statement.

for i in 1...10 {
  
  if i == 5 {
    break
  }
 
  print(i) 
}
// result 
// 1
// 2
var i = 1

while (i<=10) {
 
   if i >= 5 {
      break
   }
  
  print(i)
  i = i + 1
}
// result 
// 1
// 2
// 3
// 4
switch (year) {
    case let x where (x % 100) == 0 && (x % 400) != 0:
        break
    case let x where (x % 4) == 0:
        return true
    default:
        break
}
outerloop: for i in 1...3{

  innerloop: for j in 1...3 {

    if j == 3 {
        break outerloop
    }

    print("i = \(i), j = \(j)")
  }
}
// result
// i = 1, j = 1
// i = 1, j = 2

continue

The continue statement allows to proceed to the next step of the nearest enclosing loop.

for i in 1...3 {
  for j in 1...3 {
    
    if j == 2 {
      continue
    }
    
    print("i = \(i), j = \(j)")
  }
}
label1: for i in 1...3 {
  label2: for j in 1...3 {
    
    if j == 2 {
      continue label1
    }
    
    print("i = \(i), j = \(j)")
  }
}