Chapters

Hide chapters

Swift Apprentice: Fundamentals

First Edition · iOS 16 · Swift 5.7 · Xcode 14.2

Section III: Building Your Own Types

Section 3: 9 chapters
Show chapters Hide chapters

3. Basic Control Flow
Written by Matt Galloway

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

When writing a computer program, you must tell the computer what to do in different scenarios. For example, a calculator app would need to do one thing if the user taps the addition button and another if the user taps the subtraction button.

In computer programming terms, this concept is known as control flow, named so because various methods control the flow of the program. This chapter will teach you how to make decisions and repeat tasks in your programs using syntax to control the flow. You’ll also learn about Booleans, which represent true and false values, and how you can use these to compare data.

Comparison Operators

You’ve seen a few types, such as Int, Double and String. Here you’ll learn about another type that lets you compare values through the comparison operators.

When you perform a comparison, such as looking for the greater of two numbers, the answer is either true or false. Swift has a data type just for this! It’s called a Bool, which is short for Boolean, after a rather clever man named George Boole who invented an entire field of mathematics around the concept of true and false.

Here is how you use a Boolean in Swift:

let yes: Bool = true
let no: Bool = false

And because of Swift’s type inference, you can leave off the type annotation:

let yes = true
let no = false

A Boolean can only be true or false, denoted by the keywords true and false. In the code above, you use the keywords to set the state of each constant.

Boolean Operators

You commonly use Booleans to compare values. For example, you may have two values and want to know if they’re equal: either they are (true), or they aren’t (false).

let doesOneEqualTwo = (1 == 2)
let doesOneNotEqualTwo = (1 != 2)
let alsoTrue = !(1 == 2)
let isOneGreaterThanTwo = (1 > 2)
let isOneLessThanTwo = (1 < 2)

Boolean Logic

Each of the examples above tests just one condition. When George Boole invented the Boolean, he had much more planned for it than these humble beginnings. He invented Boolean logic, which lets you combine multiple conditions to form a result.

let and = true && true
let or = true || false
let andTrue = 1 < 2 && 4 > 3    // true
let andFalse = 1 < 2 && 3 > 4   // false

let orTrue = 1 < 2 || 3 > 4     // true
let orFalse = 1 == 2 || 3 == 4  // false
let andOr = (1 < 2 && 3 > 4) || 1 < 4  // true
1. (1 < 2 && 3 > 4) || 1 < 4
2. (true && false) || true
3. false || true
4. true

String Equality

Sometimes you want to determine if two strings are equal. For example, a children’s game of naming an animal in a photo would need to determine if the player answered correctly.

let guess = "dog"
let dogEqualsCat = guess == "cat"
let order = "cat" < "dog"

Toggling a Bool

A Bool often represents the state of something being “on” or “off”. In those cases, it’s common to toggle between states. For example, you could use a Bool to represent the state of a light switch in your application and toggle between the states of “on” and “off”.

var switchState = true
switchState.toggle() // switchState = false
switchState.toggle() // switchState = true

Mini-Exercises

  1. Create a constant called myAge and set it to your age. Then, create a constant named isTeenager that uses Boolean logic to determine if the age denotes someone in the age range of 13 to 19.
  2. Create another constant named theirAge and set it to 30. Then, create a constant named bothTeenagers that uses Boolean logic to determine if both ages denote teenagers.
  3. Create a constant named reader and set it to your name as a String. Create a constant named author and set it to my name, Matt Galloway. Create a constant named authorIsReader that uses string equality to determine if reader and author are equal.
  4. Create a constant named readerBeforeAuthor which uses string comparison to determine if reader comes before author.

The if Statement

The first and most common way of controlling the flow of a program is through the use of an if statement, which allows the program to do something only if a certain condition is true. For example, consider the following:

if 2 > 1 {
  print("Yes, 2 is greater than 1.")
}
let animal = "Zebra"

if animal == "Cat" || animal == "Dog" {
  print("Animal is a house pet.")
} else {
  print("Animal is not a house pet.")
}
let hourOfDay = 12
var timeOfDay: String

if hourOfDay < 6 {
  timeOfDay = "Early morning"
} else if hourOfDay < 12 {
  timeOfDay = "Morning"
} else if hourOfDay < 17 {
  timeOfDay = "Afternoon"
} else if hourOfDay < 20 {
  timeOfDay = "Evening"
} else if hourOfDay < 24 {
  timeOfDay = "Late evening"
} else {
  timeOfDay = "INVALID HOUR!"
}
print(timeOfDay)

Short-Circuiting

An important fact about if statements is what happens when there are multiple Boolean conditions separated by ANDs (&&) or ORs (||).

if 1 > 2 && name == "Matt Galloway" {
  // ...
}
if 1 < 2 || name == "Matt Galloway" {
  // ...
}

Constant and Variable Scope

if statements introduce a new concept scope, which controls the visibility and lifetime of constants and variables through the use of braces. Imagine you want to calculate the fee to charge your client. Here’s the deal you’ve made:

var hoursWorked = 45

var price = 0
if hoursWorked > 40 {
  let hoursOver40 = hoursWorked - 40  // hoursOver40 = 5
  price += hoursOver40 * 50           // price = 250
  hoursWorked -= hoursOver40          // hoursWorked = 40
}
price += hoursWorked * 25             // price = 1250

print(price)
...

print(price)
print(hoursOver40)

The Ternary Conditional Operator

Now I want to introduce a new operator, one you didn’t see in Chapter 2, “Types & Operations”. It’s called the ternary conditional operator and it’s related to if statements.

let a = 5
let b = 10

let min: Int
if a < b {
  min = a
} else {
  min = b
}

let max: Int
if a > b {
  max = a
} else {
  max = b
}
(<CONDITION>) ? <TRUE VALUE> : <FALSE VALUE>
let a = 5
let b = 10

let min = a < b ? a : b
let max = a > b ? a : b

Mini-Exercises

  1. Create a constant named myAge and initialize it with your age. Write an if statement to print out Teenager if your age is between 13 and 19 and Not a teenager if your age is not between 13 and 19.
  2. Create a constant named answer and use a ternary condition to set it equal to the result you print out for the same cases in the above exercise. Then print out answer.

Loops

Loops are Swift’s way of executing code multiple times. In this section, you’ll learn about one type of loop: the while loop. If you know another programming language, you’ll find the concepts and maybe even the syntax familiar.

While Loops

A while loop repeats a code block while a condition is true. You create a while loop this way:

while <CONDITION> {
  <LOOP CODE>
}
while true {  }
var sum = 1

while sum < 1000 {
  sum = sum + (sum + 1)
}

repeat-while Loops

A variant of the while loop is called the repeat-while loop. It differs from the while loop in that the condition is evaluated at the end of the loop rather than at the beginning. You construct a repeat-while loop like this:

repeat {
  <LOOP CODE>
} while <CONDITION>
sum = 1

repeat {
  sum = sum + (sum + 1)
} while sum < 1000
sum = 1

while sum < 1 {
  sum = sum + (sum + 1)
}
sum = 1

repeat {
  sum = sum + (sum + 1)
} while sum < 1

Breaking Out of a Loop

Sometimes you want to break out of a loop early. You can do this using the break statement, which immediately stops the loop’s execution and continues on to the code after the loop.

sum = 1

while true {
  sum = sum + (sum + 1)
  if sum >= 1000 {
    break
  }
}

Mini-Exercises

  1. Create a variable named counter and set it equal to 0. Create a while loop with the condition counter < 10, which prints out counter is X (where X is replaced with counter value) and then increments counter by 1.
  2. Create a variable named counter and set it equal to 0. Create another variable named roll and set it equal to 0. Create a repeat-while loop. Inside the loop, set roll equal to Int.random(in: 1...6), which means to pick a random number between 1 and 6. Then increment counter by 1. Finally, print After X rolls, roll is Y where X is the value of counter and Y is the value of roll. Set the loop condition so the loop finishes when the first 1 is rolled.

Challenges

Before moving on, here are some challenges to test your knowledge of basic control flow. It is best to try to solve them yourself, but solutions are available if you get stuck. These came with the download or are available at the printed book’s source code link listed in the introduction.

Challenge 1: Find the Error

What’s wrong with the following code?

let firstName = "Matt"

if firstName == "Matt" {
  let lastName = "Galloway"
} else if firstName == "Ray" {
  let lastName = "Wenderlich"
}
let fullName = firstName + " " + lastName

Challenge 2: Boolean Challenge

In each of the following statements, what is the value of the Boolean answer constant?

let answer = true && true
let answer = false || false
let answer = (true && 1 != 2) || (4 > 3 && 100 < 1)
let answer = ((10 / 2) > 3) && ((10 % 2) == 0)

Challenge 3: Snakes and Ladders

Imagine you’re playing a game of snakes & ladders that goes from position 1 to position 20. On it, there are ladders at positions 3 and 7, which take you to 15 and 12, respectively. Then there are snakes at positions 11 and 17, which take you to 2 and 9, respectively.

Challenge 4: Number of Days in a Month

Given a month (represented with a String in all lowercase) and the current year (represented with an Int), calculate the number of days in the month. Remember that because of leap years, February has 29 days when the year is a multiple of 4 but not a multiple of 100. February also has 29 days when the year is a multiple of 400.

Challenge 5: Next Power of Two

Given a number, determine the next power of two greater than or equal to that number.

Challenge 6: Triangular Number

Given a number, print the triangular number of that depth. You can get a refresher on triangular numbers here: https://en.wikipedia.org/wiki/Triangular_number

Challenge 7: Fibonacci

Calculate the nth Fibonacci number. Remember that Fibonacci numbers start their sequence with 1 and 1, and then subsequent numbers in the sequence are equal to the previous two values added together. You can get a refresher here: https://en.wikipedia.org/wiki/Fibonacci_number

Challenge 8: Make a Loop

Use a loop to print out the multiplication or times table up to 12 of a given factor.

Challenge 9: Dice Roll Table

Print a table showing the number of combinations to create each number from 2 to 12, given two six-sided dice rolls. You should not use a formula but compute the number of combinations exhaustively by considering each possible dice roll.

Key Points

  • You use the Boolean data type Bool to represent true and false.
  • The comparison operators, all of which return a Boolean, are:
Ojiec == Gixi Isepawiv Quh Oleor Wosc vxid Dnaotuk ppuj Girx wjiq om ekuuf Rpoitat zcar or ajaow != < > <= >=

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now