Swift - Control Flow
Published: 2022-04-02 16:24:10

3 kinds of control flow

- **Loops**
  1. For-In
  2. While
  3. Repeat-While

- **Conditional Statement**
  1. If
  2. Switch

- **Control Transfer Statements**
  1. continue
  2. break
  3. fallthrough
  4. return
  5. throw

---

### For-In Loops
For-in loop is used to iterate over a sequence, such as items in an array, dictionary, Set, ranges of numbers, or characters in a string.

example : 

``` swift
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
    print("Hello, \(name)!")
}
```

use **stride(from:to:by:)** or **stride(from:through:by:)** after in to partially loop over at different intervals.

 **_For-In loop can be used to iterate any collection, including own classes and collection types, as long as those types conform to the Sequence protocol._**

---

### While Loops
use while loops when the number of iterations isn’t known before the first iteration begins.
two kinds of while loops:

1. **while** evaluates its condition at the start
2. **repeat-while** evaluates its condition at the end 

---

###If
It executes a set of statements only if that condition is true, If false then it executes the statements in else clause if any present. else clause is optional. 

example : 

``` swift
temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
    print("It's really warm. Don't forget to wear sunscreen.")
} else {
    print("It's not that cold. Wear a t-shirt.")
}
```

multiple else clause can be chained together

---

###Switch

 A switch statement provides an alternative to the if statement for responding to multiple potential states. It takes a value and compares it against several possible matching patterns. It then executes an appropriate block of code

**_Every switch statement must be exhaustive. That is, every possible value of the type being considered must be matched by one of the switch cases. If it’s not appropriate to provide a case for every possible value, you can define a default case to_**

example : 

``` swift
let someCharacter: Character = "z"
switch someCharacter {
case "a":
    print("The first letter of the alphabet")
case "z":
    print("The last letter of the alphabet")
default:
    print("Some other character")
}
```

**compound case** can be used to combine 2 value in a case separated by comma.

example : 

``` swift
case "a", "A":
    print("The letter A")`
```

Values in switch cases can be a range

``` swift
example : 
`case 0:
    naturalCount = "no"
case 1..<5:
    naturalCount = "a few"
case 5..<12:
    naturalCount = "several"
```

**tuples** can be used to test multiple values in the same switch statement. along with tuples underscore character (_), also known as the wildcard pattern, to match any possible value.

example : 

``` swift
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")
default:
    print("\(somePoint) in plane")
}
```

**Value Bindings** - switch case can name the value or values it matches to temporary constants or variables, for use in the body of the case.

example :

``` swift
switch somePoint {
case (let x, 0):
    print("on the x-axis with an x value of \(x)")
case (0, let y):
    print("on the y-axis with a y value of \(y)")
case let (x, y):
    print("somewhere else at (\(x), \(y))")
}
```

**where** clause can be used with switch to check for additional conditions.

example : 

``` swift
switch somePoint {
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")
}
```

**Compound cases** can also include **value bindings**. All of the patterns of a compound case have to include the same set of value bindings

example : 

``` swift
switch somePoint {
case (let distance, 0), (0, let distance):
    print("On an axis, \(distance) from the origin")
default:
    print("Not on an axis")
}
```

---

## Control Transfer Statements

## Continue
continue statement stop current iteration of loop and start again at the beginning of the next iteration through the loop

## Break
The break statement ends execution of an entire control flow statement immediately. It can be used in a switch or loop statement to exit early.

## Fallthrough
It can be used inside the switch case body to jump into the next case without matching condition.

example : 

``` swift
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough
default:
    description += " an integer."
}
```

---

## Labeled Statements

It can be used to **break** or **continue** nested loop / nested conditional statement.

example :

``` swift
outerLoop : for element1 in array1{
    for element2 in array2{
        if(element1 == element2){
            continue outerLoop
        }
    }
    uniqueElemetsInArray1.append(element1)
}
print(uniqueElemetsInArray1)  //[21, 13, 5]
```