Date:

Share:

Swift enum pattern matching with extra conditions

Related Articles

In this post we are going to explore how we can provide more precise conditions for pattern matching when working with enums in Swift. The most common use case is using switch Statements with the where clause to gain more control over the terms of the case. But we will also examine the use of where Section B for-in Loops to avoid unnecessary iterations. And finally, we’ll see how to add more conditions while Loops and if-case when statements where section is not available.

Let’s consider a dish TransportationEvent Representation of different types of events in a transportation system.

enum TransportationEvent {
    case busArrival(busNumber: Int, passengers: Int)
    case trainArrival(trainNumber: Int, passengers: Int, cargoLoad: Int)
    case bicycleArrival
}

Now, imagine that we have a system that handles these events. A basic switch statement might look like this.

let event = TransportationEvent.busArrival(busNumber: 42, passengers: 15)

switch event {
case .busArrival(let busNumber, let passengers):
    print("Bus (busNumber) arrived with (passengers) passengers.")
case .trainArrival(let trainNumber, let passengers, let cargoLoad):
    print("Train (trainNumber) arrived with (passengers) passengers and (cargoLoad) tons of cargo.")
case .bicycleArrival:
    print("A bicycle arrived.")
}

It works, but what if we want to differentiate between events according to the number of passengers or the amount of luggage? This is when we will need to add some additional conditions.

where Section B switch Statements

We can take advantage of where Section to add specific terms in our cases in a switch Statement in Swift. we are ripe TransportationEvent This enum example can help us differentiate between events based on the number of passengers or the amount of cargo.

switch event {
case .busArrival(let busNumber, let passengers) where passengers < 10:
    print("Bus (busNumber) arrived with only a few passengers.")
case .busArrival(let busNumber, let passengers):
    print("Bus (busNumber) arrived with (passengers) passengers.")
case .trainArrival(let trainNumber, let passengers, let cargoLoad) where cargoLoad > 50:
    print("Train (trainNumber) arrived with (passengers) carrying a heavy cargo load.")
case .trainArrival(let trainNumber, let passengers, let cargoLoad):
    print("Train (trainNumber) arrived with (passengers) passengers and (cargoLoad) tons of cargo.")
case .bicycleArrival:
    print("A bicycle arrived.")
}

where Section B for-in Loops

In addition to switch Statements, e where A clause can also be leveraged in a for-in A loop for repeating elements that meet specific conditions. When repeating a collection or sequence, e where A section allows us to filter the elements and repeat only those that meet certain criteria. This allows us to process or manipulate the desired subset of elements within the loop.

For example, let us consider the TransportationEvent enum we worked with. Let’s say we have an array of transport events, and we want to iterate over them only on busArrival Events where the number of passengers is greater than 10. We can achieve this through the where Section comes for-in loop as follows.

let transportationEvents: [TransportationEvent] = [
    .busArrival(busNumber: 1, passengers: 5),
    .busArrival(busNumber: 2, passengers: 15),
    .trainArrival(trainNumber: 10, passengers: 50, cargoLoad: 100),
    .busArrival(busNumber: 3, passengers: 20),
    .bicycleArrival
]

for case let .busArrival(busNumber, passengers) in transportationEvents where passengers > 10 {
    print("Bus (busNumber) arrived with (passengers) passengers.")
}

In this example, the where The clause is used for-in loop to filter the busArrival Events where the number of passengers is greater than 10. only you busArrival Events with more than 10 passengers will be processed within the loop.

Additional conditions b while Loops

To add additional conditions while loops we can use comma syntax instead of where section. The comma basically behaves like a logical AND operator, ensuring that all conditions are met.

So if we want to keep processing transport events while they are the arrival of buses with some passengers and stop as soon as our conditions are not met, we can write the following loop.

var index = 0
while case let .busArrival(busNumber, passengers) = transportationEvents[index], passengers > 0 {
    print("Processing bus (busNumber) arrival with (passengers) passengers.")
    index += 1
}

In this example, the while A loop specifies two conditions separated by a comma. The first checks if the current element b transportationEvents[index] Compatible with busArrival case, and the second ensures that the number of passengers is greater than 0. Only when both conditions are met will the loop return and process the event.

Additional conditions b if-case Statements

If we need to add more conditions in control flow statements, such as if-caseWe can use the same comma syntax that we used with a while loop. Suppose we want to check whether a single transport event is a busArrival with more than 10 passengers. We can achieve this by using the if-case statement, as shown below.

let event = TransportationEvent.busArrival(busNumber: 42, passengers: 15)

if case let .busArrival(busNumber, passengers) = event, passengers > 10 {
    print("Processing bus (busNumber) arrival with (passengers) passengers.")
}

The comma-separated condition ensures that the busArrival The event has more than 10 passengers before the code block is executed. This allows us to conditionally handle specific scenarios based on our pattern matching criteria.

Using the techniques we’ve explored in this post, we can add a layer of flexibility and expressiveness to our pattern matching cases in Swift. whether we use switch Statements, loops or control flow statements like if-caseWe can handle complex scenarios with precision and clarity.

Integrating SwiftUI in UIKit apps by Natalia Panprovova book cover
WWDC23 proposal

our book “Integrating SwiftUI in UIKit apps” now 40% discount!

Discover different ways to adopt SwiftUI in existing UIKit projects and take full advantage of the new iOS 16 frameworks and APIs such as Swift Charts.

The sale is active until 19.6.

If you enjoy our blog and would like to support us, you can Sponsor us on GitHub.

For blog updates and development tips, follow us on Twitter @nilcoalescing.

Source

Popular Articles