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.
}
コメント