4.5 Pattern Matching
The idea of pattern matching in conditionals is not new to Swift 2. The fundamentals have been available in the language for a while. But in Swift 2 the idea has been enhanced and added to more aspects of the language, making certain scenarios even easier to handle. Let's check it out.
1.Introduction3 lessons, 15:05
2.Foundational Concepts5 lessons, 43:51
3.Working With Collections3 lessons, 26:26
4.Controlling Flow7 lessons, 1:22:24
5.Functions5 lessons, 51:54
6.Creating Types6 lessons, 1:08:10
7.Conclusion1 lesson, 01:15
4.5 Pattern Matching
The next thing that I'd like to discuss is a topic called pattern matching. And while we could spend an awful lot of time going through all the ins and outs and nuances of pattern matching, really the basics will suffice. And really to this point we've actually talked a little bit about pattern matching, but not necessarily in those terms. So we've talked a little bit about ranges and we've talked a little bit about wild cards using the underscore, and we've created some variables and constants and we've started to work with tuples and all of those things are going to live within the world of pattern matching. And once you see them within context then it’s gonna start to make a little bit more sense to you. So let’s start taking a look at some of the basics. So let’s just review some of the things that we’ve already done that could be considered part of the world of patterns and, ultimately, pattern matching. So what exactly is a pattern? Well we’ve seen patterns in a couple of different ways. We’ve created four loops. So let’s say I wanted to do something like for, and I will use the wild card, the underscore, and then I'm gonna say for whatever, some sort of wild card in, let's give it a range. Let's say 2 through 7. I want to do something. Maybe I wanna print something out, maybe I wanna execute something some number of times. And what we've done here is we've actually created a pattern. This wild card and using it in this form is referred to as the wild card pattern. So we're using this wild card to refer to some value that we don't necessarily care about. We just want to make sure that we run through this loop a couple of times. So this is a valid, a wild card pattern. Now there's another pattern referred to as the identifier pattern. And the identifier patterning is actually extremely comical to look at. But if you've ever created a variable or a constant, like let some value, be equal to 50, you have done or have created what's known as the identifier pattern. Which really does nothing more than matches some value or binds some value, in this case 50, to some variable or constant name, which in this case is some value. And that process of creating that association or that binding is referred to as the identifier pattern. Now albeit those are somewhat boring and maybe not very interesting, we can get a little bit more interesting and a little bit more complicated when we start talking about some additional patterns that come along with tuples. So let’s see how we could do something like that. So let’s start with a very basic concept of trying to understand some basic value binding patterns. And what I mean by value binding is we’re going to produce really a tuple, very similarly to how we did in the lesson on tuples, when we created a tuple. I think we did something like employee equal to, and we created an employee ID 12345, and a name Derek. And then later on, we did this. We said, let open and close parentheses, and we gave it two variable names. We said id and name, and we set that equal to our tuple. Now this process here of binding the values that are associated with, in this case, a tuple to a couple of variable names is called the value binding pattern. So we're binding the values that are found within this tuple to the variables found here within this pattern here, within these two values. So that's the basic concept behind a value-binding pattern. So what is that useful for? While it's useful for a number of different things and one of the reasons why I included this section with controlling the flow of your application is because you're gonna see a lot of these types of things when you start to do things like switch statements. So let's see how something like that would work out. So let's say we were dealing with like I said before, an employee of some sort. So we wanted to create an employee and we'll once again do 12345, and this is going to be Derek Jensen. And then we wanted to do some sort of logic around this. We wanted to do some sort of switch statement and we wanted to do a switch on an employee. So right now we are going to go through some logic and we're going to create some case statements that are ultimately going to see what type of employee or what sort of case this employee is going to fall into and then we're going to do something with it. But how do we switch on an employee? This is a tuple, there's two values here. How do we get access to that so we can do something with it? How do we pattern match against this employee, this tuple? Well we use the value binding pattern that we just talked about. So we're gonna create a case statement. And we're going to use the let keyword, so let is going to allow us to create this twosome named constants that we're ultimately going to able to refer to the values here. So once again we'll do the same thing. We'll say let ID and name and we'll have a colon. And we'll pop down a line, we'll reindent this, and we'll pop down a line and we'll be able to do something like print the employee name is and then we'll just go ahead and do some string interpolation and we'll refer to name here. Now I could refer to name. I could refer to ID. I could do really anything that I want and it will be just fine. So really what we've done here is we've created a very simple case statement that's going to match to this value here. So I could go ahead and save this and I could run my application and we would expect at this point that the value passed in for employee is going to map to this case statement. Then we will get access to these values via ID and name. And then we can print out the employee name is Derek Jenson. Well, so what, you say. Every time I pass employ in it's going to fall into here. So I could change the name and I could change the name to Derek Johnson and save this and run it and it's going to continue to hit this. So what's the big deal? Well the power comes in when I start to need to get access to maybe different types of employees or maybe different versions here and there and we can do that by creating multiple case statements. So I could create another case statement and we'll say let and this time let's say maybe I'm only interested in the employees who may be, this is going to be a silly example, maybe don't have a name in the system yet. So we'll say, let ID, and this case, we either are going to deal with something, or some value here that we don't necessarily care about, so we could use the wild card if we wanted, but we could also say what if their name is just null. What if there's nothing in there? What if it's an empty name? And if that's the case, then we can go ahead and create a line here that's going to say print employee ID, doesn't have a name. Now that seems somewhat silly, but for this example it will work. So I can go ahead and change this now and I can say, you know what, this employee ID doesn't have a name or has an empty name. And I could run this and it would once again say employee 12345 doesn't have a name. So it could create a bunch of different variations of this in my Swift statement to get all of these to ultimately match and run down and do some sort of custom logic based on these patterns that are matching against here using this case let statement. So that's pretty cool so I have a lot of powerful functionality there. Now this is pretty cool but let's say, for example, I have a certain system maybe a bill system, where the employee IDs from some number up to some number, their paychecks go out on maybe the first Thursday of the month and the other half of the employees have their paychecks go out on the second Thursday of the month, or maybe every other week or something like that, and I need to be able to keep these things straight. How could I do something like that with a switch statement? Well if you head to go ahead and continuously look up this information in a table, in a database, or have to maybe run this check through a bunch of series of numbers to figure out where This thing falls, it could get very, very messy very quickly. But if I use some basic pattern matching I could do something pretty nice here. But how do I use what we've learned so far to be able to match that way? Well what I can do is I could take this value binding pattern and I could put it together with a range and I could start to figure it out that way. So let's say that I came in here and we're no longer looking for the empty name. So let's, in this case say, I wanted to find all of the employees whose IDs went from one up to 12345, and they would get paid on the first Thursday, and everybody else is gonna get paid on the second Thursday. So I could ultimately switch this up just a little bit. So i could create my case statement with my open and closed parenthesis. So now we're not necessarily binding any values, we're not using the let statement, but we can start to refer two values found with this employee. So let's say I wanted to refer to all the employees who have IDs that range from one up to 12345. And then the second value that comes in, I don't really care about. I'm not really too concerned about, so I'm just gonna use the wildcard here cuz I don't really care, I'm not gonna do anything with it. And then I'm going to drop down to the next line, and I'm simply going to print. And I could do the ugly method here of referring to a name if I wanted by saying Employee dot zero needs to get paid on the first Thursday, and I could go ahead and save that and at this point, if I wanted to run it, it's not going to let me because once, like I mentioned before. The switch statements needs to be exhaustive. I need to be able to refer to every single opportunity, or every single option there is for the input, so that I can account for that. Now there is a couple different ways you can do that. You can at this point, you can create a default. And this default is going to ultimately be the one that is going to catch all the other things and I could put in some sort of logic in there. Or at this point, instead of doing that I could create another case statement that is going to refer to all the other values that are found within the set that could possibly come in, as far as this tuple is concerned. So I could do that by saying case, I want to kind of create a catch all here, I'm gonna say I want to catch a wild card, and a wild card, and this is gonna kind of refer to everything after this, and I can simply say at this point print, employee dot zero needs to get paid on the second Thursday. And I could go ahead and save that. Now I'm going to build properly, I'm not gonna have that error anymore because my Swift statement is now exhaustive. Now one note here, remember this is kinda ugly, this employee dot zero, you can do this, it's kinda frowned upon a little bit, so I could've come in here and said employee ID and name. And then in here, I could have referred to this as .name and .name. And I could go ahead and save that. And if I were to run this example now, you're gonna see that nobody apparently needs to get paid on the first day, cuz I don't have a name here. So I could just put me, I could save that and run. So it'll say now that me needs to get paid on the first Thursday and if I were to add another value here and make this go up to six, I could save that and run it now and it's going to say that me needs to be paid on the second Thursday. So you see now that this whole concept of pattern matching becomes extremely powerful especially in the world of say switch statements where I need to match some values with a particular piece of control flow statement, in this case, a switch statement, so that I could find when a particular value, in this case a tupple falls into a range and then I could process it that way and then I could catch everything out and do it some other way. So this is pretty cool and I could create as many case statements of any variations that I want in here. Remember that these tuples can contain many, many different values in here that we could refer to. It doesn't just have to be two, it could be five and I could create exhaustive pattern of case statements here that would have to match all the different five and so you can get very, very complex, very quickly. But this is just a basic concept behind being able to do some of this pattern matching because it's ultimately pretty cool. And we'll find another couple of ways that we're going to be able to use these later on in the course.