top of page
Writer's pictureJennifer Eve Vega

Swift: Switch Tuple

Using tuples in switch allows us to match multiple values at once. It also makes our code readable and easy to understand.


This was very confusing to me at first. It's like I understood the concept, and what it's meant to do, but at the same time, when I code it, I just simply get lost and I couldn't quite get how I should code the logic, and would take a while to fully write the code with swift tuple. If you have the same struggle with me, here are some examples that might help us get on track when writing swift tuples.


Switch Tuple with Structs

enum ProgramId: Int {
    case BSIT = 123
    case BSCS = 120
}
struct Student {
    struct Name {
        var firstName: String
        var lastName: String
        
        var fullName: String {
            return "\(lastName), \(firstName)"
        }
    }
    var studentId: String
    var name: Name
    var program: ProgramId
    var year: UInt
}

Let's say you have a list of students that you want to group by year and program.

for student in students {
    switch (student.program, student.year) {
    case (.BSCS, 1):
        debugPrint("\(student.name.fullName) is a BSCS-1 student")
    case (.BSCS, 2):
        debugPrint("\(student.name.fullName) is a BSCS-2 student")
    case (.BSCS, 3):
        debugPrint("\(student.name.fullName) is a BSCS-3 student")
    case (.BSCS, 4):
        debugPrint("\(student.name.fullName) is a BSCS-4 student")
    case (.BSIT, 1):
        debugPrint("\(student.name.fullName) is a BSIT-1 student")
    case (.BSIT, 2):
        debugPrint("\(student.name.fullName) is a BSIT-2 student")
    case (.BSIT, 3):
        debugPrint("\(student.name.fullName) is a BSIT-3 student")
    case (.BSIT, 4):
        debugPrint("\(student.name.fullName) is a BSIT-4 student")

    default:
        debugPrint("Not valid")
    }
}

The switch tuple made the code easy to read and understand. Another example, let's say you have a list of students that you want to group by program.

for student in students {
    switch (student.program, student.year) {
    case (.BSCS, _):
        bscsStudents.append(student)
    case (.BSIT, _):
        bsitStudents.append(student)
    }
}

Another example is we have an struct with different boolean variables:

typealias PriorityLevel = Int

struct TaskPrioritization {
    var isUrgent: Bool
    var isImportant: Bool
}

And we want to know the priority level based on the values in TaskPrioritization:

struct TaskPrioritization {
    var isUrgent: Bool
    var isImportant: Bool
    
    func getPriorityLevel() -> PriorityLevel {
        switch (isUrgent, isImportant) {
        case (true, true):
            // Both are urgent and important
            return PriorityLevel(1)
        case (true, false):
            // Urgent but not important
            return PriorityLevel(2)
        case (false, true):
            // Not urgent but important
            return PriorityLevel(3)
        case (false, false):
            // Not urgent and not important
            return PriorityLevel(4)
        }
    }
}

We can call this by:

let doItNowTask = TaskPrioritization(isUrgent: true, isImportant: true)
let priority = doItNowTask.getPriorityLevel()

The PriorityLevel of doItNowTask is Level 1.

Aside from readability, since swift tuple makes our logic pretty straight-forward, it is also easy to do a unit test with swift tuple.

final class MyTest: XCTestCase {
    func testLevel1Priority() {
        let task = TaskPrioritization(isUrgent: true, isImportant: true)
        let priority = task.getPriorityLevel()
        XCTAssertEqual(priority, 1)
    }
    
    func testLevel2Priority() {
        let task = TaskPrioritization(isUrgent: true, isImportant: false)
        let priority = task.getPriorityLevel()
        XCTAssertEqual(priority, 2)
    }
    
    // test other levels
}

Please note that swift tuples are not limited to 2 values to match, we can add more if needed, for the sake of an example, I'm going to update the TaskPrioritization struct:

struct TaskPrioritization {
    var isUrgent: Bool
    var isImportant: Bool
    var isSomethingElse: Bool
}
switch (isUrgent, isImportant, isSomethingElse): {
	case (true, true, true):
		debugPrint("Is Urgent, is important, is something else"
	
	....
	
	default:
		//If you can't add any more specific instructions for the rest of the matches, just add a default case.
}

Recent Posts

See All

コメント


bottom of page