The case
and where
statements within a switch
statement can be very powerful. Using case
and where
statements within conditional statements can also make our code much smaller and easier to read. Conditional statements, such as if
, for
, and while
, can also make use of the where
and case
keywords. Let's look at some examples, starting off with using the where
statement to filter the results in a for-in
loop.
Filtering with the where statement
In this example, we will take an array of integers and print out only the even numbers. However, before we look at how to filter the results with the where
statement, let's look at how to do this without the where
statement:
for number in 1...30 { if number % 2 == 0 { print(number) } }
In this example, we use a for-in
loop to cycle through the numbers 1 to 30. Within the for-in
loop, we use an if
conditional statement to filter out the odd numbers. In this simple example, the code is fairly easy to read, but let's see how we can use the where
statement to use fewer lines of code and make them easier to read:
for number in 1...30 where number % 2 == 0 { print(number) }
We still have the same for-in
loop as in the previous example. However, we have now put the where
statement at the end; therefore, we only loop through the even numbers. Using the where
statement shortens our example by two lines and makes it easier to read because the where
clause is on the same line as the for-in
loop, rather than being embedded in the loop itself.
Now let's look at how we could filter with the for-case
statement.
Filtering with the for-case statement
In this next example, we will use the for-case
statement to filter through an array of tuples and print out only the results that match our criteria. The for-case
example is very similar to using the where
statement where it is designed to eliminate the need for an if
statement within a loop to filter the results. In this example, we will use the for-case
statement to filter through a list of World Series winners and print out the year(s) a particular team won the World Series:
var worldSeriesWinners = [ ("Red Sox", 2004), ("White Sox", 2005), ("Cardinals", 2006), ("Red Sox", 2007), ("Phillies", 2008) ] for case let ("Red Sox", year) in worldSeriesWinners { print(year) }
In this example, we created an array of tuples named worldSeriesWinners
, where each tuple in the array contained the name of the team and the year that they won the World Series. We then use the for-case
statement to filter through the array and only print out the years that the Red Sox won the World Series. The filtering is done within the case
statement, where ("Red Sox", year)
states that we want all the results that have the string Red Sox in the first item of the tuple, and the value of the second item in the year constant. The for-in
loop then loops through the results of the case
statement, printing out the value of the year constant.
The for-case-in
statement also makes it very easy to filter out the nil
values in an array of optionals. Let's look at an example of this:
let myNumbers: [Int?] = [1, 2, nil, 4, 5, nil, 6] for case let .some(num) in myNumbers { print(num) }
In this example, we created an array of optionals named myNumbers
that could contain either an integer value or nil
. An optional is internally defined as an enumeration, as shown in the following code:
enum Optional<Wrapped> { case none, case some(Wrapped) }
If an optional is set to nil
, it will have a value of none
, but if it is not nil
it will have a value of some
, with an associated type of the actual value. In our example, when we filter for .some(num)
, we are looking for any optional that has a non-nil value. As shorthand for .some()
, we could use the ?
(question mark) symbol, as we will see in the following example. This example also combines the for-case-in
statement with a where
statement to perform additional filtering.
let myNumbers: [Int?] = [1, 2, nil, 4, 5, nil, 6] for case let num? in myNumbers where num > 3 { print(num) }
This example is the same as the previous example, except that we have inputted the additional filtering with the where
statement. In the previous example, we looped through all of the non-nil values, but in this example, we have looped through the non-nil values that are greater than 3. Let's see how we do this same filtering without the case
or where
statements:
let myNumbers: [Int?] = [1, 2, nil, 4, 5, nil, 6] for num in myNumbers { if let num = num { if num > 3 { print(num) } } }
Using the for-case-in
and where
statements can greatly reduce the number of lines needed. It also makes our code much easier to read because all the filtering statements are on the same line.
Let's look at one more filtering example. This time, we will look at the if-case
statement.
Using the if-case statement
Using the if-case
statement is very similar to using the switch
statement. Most of the time the switch
statement is preferred when we have over two cases we are trying to match, but there are instances where the if-case
statement is needed. One of those times is when we are only looking for one or two possible matches, and we do not want to handle all the possible matches. Let's look at an example of this:
enum Identifier { case Name(String) case Number(Int) case NoIdentifier } var playerIdentifier = Identifier.Number(2) if case let .Number(num) = playerIdentifier { print("Player's number is \(num)") }
In this example, we created an enumeration named Identifier
that contains three possible values: Name
, Number
, and NoIdentifier
. We then created an instance of the Identifier
enumeration named playerIdentifier
, with a value of Number
and an associated value of 2. We then used the if-case
statement to see if the playerIdentifier
had a value for Number
and; if so, we printed a message to the console.
Just like the for-case
statement, we can perform additional filtering with the where
statement. The following example uses the same Identifier
enumeration as we used in the previous example:
var playerIdentifier = Identifier.Number(2) if case let .Number(num) = playerIdentifier, num == 2 { print("Player is either XanderBogarts or Derek Jeter") }
In this example, we have used the if-case
statement to see if the playerIdentifier
had a value of Number
, but we also added the where
statement to see if the associated value was equal to 2. If so, we identified the player as either XanderBogarts or Derek Jeter
.