Mohamed Omar

100 Days of SwiftUI - Day 6

It's finally time to talk loops in 100 Days of SwiftUI.

For the most part — at least at this point — looping seems fairly straightforward.

We have two types of loops:

  1. For loops
  2. While loops

For loops

Like many other programming languages, Swift's for loop looks like this:

for something in listOfThings {
  execute some code on that something
}

something in this case is what's called the loop variable, while the code in the curly braces is the loop body. The variable is available in the loop body during every iteration.

One neat feature in Swift is the ability to ignore a loop variable when you don't need it.

let numbers = [1, 2, 3]

for _ in numbers {
  print("These numbers suck!")
}

While loops

For loops automatically stop once they've reached the end of an array. While loops run until a condition stops being true.

This type of loop might be handy in some situations, but I've yet to encounter a problem that needed to be solved with a while loop. (I'm also very talented at accidentally creating infinite loops.)

But for the purposes of learning, say we wanted to keep track of a user's score to let them know when they've gotten close to beating a record. We could write:

var score = 0
let highScore = 1000

while score > highScore {
  print("You're close to beating the high score!")
}

This works, but it would get annoying very fast. We'd be printing a message for as long as the user doesn't beat that score. If I'm playing, this could take several decades.

Instead, we can add an early check to see if the user is even remotely close to the score. If they're not, we don't do anything.

var score = 0
let highScore = 1000

while score < highScore {
    score += 100
  if (highScore - score <= 200) {
      print("With \(score), you're close to beating the all-time high score!")
  }
}

//With 800, you're close to beating the all-time high score!
//With 900, you're close to beating the all-time high score!
//With 1000, you're close to beating the all-time high score!

Ranges

Loops can also be used in conjunction with ranges, which are Swift's method of creating series of numbers.

For example, if I wanted to put every number between 0 (the lower bound) and 50 (the upper bound) into an array, and then do something that many times, I could write:

for number in 1...50 {
  print("The current number is \(number)")
}

We can also use ranges to select parts of an array. If I only want certain items in an array, like the second, third and fourth items, I can typemyArray[1...3]

There's also a half-open range, which excludes the upper bound. So 1..<50 would give us every number from 1 to 49.

Checkpoint time!

After a meaty lesson on loops, it's time for a checkpoint. This quiz is a classic fizzBuzz problem (who doesn't love those?) that is meant to solidify what we've learned so far about loops.

The assignment is to loop from 1 to 100, and then for each number:

If it’s a multiple of 3, print “Fizz”
If it’s a multiple of 5, print “Buzz”
If it’s a multiple of 3 and 5, print “FizzBuzz”
Otherwise, just print the number.

Here's how I tackled it:

for number in 1...100 {
    if (number % 3 == 0 && number % 5 == 0) {
        print("FizzBuzz")
    } else if (number % 3 == 0) {
        print("Fizz")
    } else if (number % 5 == 0) {
        print("buzz")
    } else {
        print(number)
    }
}

First we create a closed range of 1 to 100 (remember, this includes the upper bound). Then we loop over the range and check the loop variable during every iteration.

I used the modulo operator to check if the current loop variable was a multiple of 3 or 5, but I did not know that Swift has a built in isMultiple method! This is sweet and can clean up the code.

An alternative solution using that method would look like this:

for number in 1...100 {
    if (number.isMultiple(of: 3) && number.isMultiple(of: 5)) {
        print("FizzBuzz")
    } else if number.isMultiple(of: 3) {
        print("Fizz")
    } else if number.isMultiple(of: 5) {
        print("buzz")
    } else {
        print(number)
    }
}

And that's all for Day 6!