[MUSIC] A really powerful data structure that you have available to you in programming with Objective-C is the NSDictionary. It's hard to explain the NSDictionary to someone that's never used something like this. They go by different names in other programming languages. Sometimes they're called associative arrays, sometimes they're called dictionaries like they are in Objective-C, and sometimes they're called maps, like for example in Java. And what they are, at a high level, is a data structure that allows you to keep track of key value pairs. And it's kind of like combining a set within array. And what you're gonna do is you're gonna have a bunch of pairs that are kept track of in your dictionary object, and the keys are the first element of the pair, and the values are the second element of the pair. And so, we're gonna put them together, so that each element from a set, which is the keys, is gonna match with an element from an array, but you're gonna access them as pairs rather than through a list or a set, which what's similar about it is that, the keys have to be unique. NSDictionary is immutable. We're looking at a bunch of immutable data structures, and that means that once you create the dictionary, you can't change it without making a copy of it, and that can have implication for memory management. If you wanna know the definitive list of all of the ways in which you can use it, the methods that are available, possibly any changes that happened to NSDictionary, make sure you do either web search for NSDictionary documentation, and you'll find the developer.apple.com website should come up very high in the list. That's the definitive location for information about the dictionary. If you need help on a method or some other information. One of the first things you're probably gonna wanna do with a dictionary is to create one. And a dictionary is one of the Objects, with which you can use the @ literal notation. So if you use at, and then you put curly braces after it, that is an indication to bundle the data that follows the at curly braces into an NSDictionary object by Objective-C. And so, in this case, what we have is we have an example of a dictionary created called dinnerRequests. We have a whole bunch of different NSStrings in there, and you can see they're separated by a colon, and then the end of the line has a comma. And so, what that is, is it's a sequence of key and value pairs. And they're matched one to the other around the colon. So Don's matched with tofurkey, Sandy's matched with burrito, Julius' matched with chicken, Theo's matched with hamburger, Joy is matched with burrito, Martha is matched with pixy sticks, and Coconut is matched with kibble. Now, in this example we're using all strings, both for our keys and our values. And that doesn't have to be the case. You can use any object pointer you want, for either the key or the value. Typically, keys are pretty commonly used. NSStrings are typically used for keys, although not always, it's a very common case to use NSStrings for the keys. But the values are often very different kinds of objects depending on what your application is. They can be a object within an object too. So your value could be a set, your value could be another dictionary, your value could be a number. Or it could be any number of different things. So in this example, when we go and we output that NSDictionary, you can see we're not iterating through it, we're just directly calling the description method on the dinnerRequest object via the format token percent app. And when we do that, the NSDictionary turns it's contents into a string, and it looks like that. The part of the string that it puts out is the curly braces as well. And you can see that it said Coconut = kibble, Don = tofurkey, Joy = burrito, etc, etc. And one thing you can see here is that a NSDictionary's not ordered. So in that sense, it's like a set, because although you have a lot of pairs and the pairs have a tight grasp with each other, the order in which those pairs come out of a dictionary is not guaranteed at all. The other thing, I don't know if it's clear or not from this example, but the keys have to be unique. If you try and put a key into NSDictionary a second time, regardless of what its value is. The first key will be overridden. Or you'll get an error, depending on the situation. So it's okay to have multiple values, though. So in this example, you can see that both Sandy and Joy are matched with burrito. But that's a value, and the value can be repeated. So this is a different way of creating an NSDictionary, not just the literal value with the at symbol and the curly braces, but also a call to the class NSDictionary. With the message dictionary with objects and keys. So something to be careful about here is that, this is just a long list. There's no colons in this list, and so you have to remember to alternate between one thing and the other thing. And the other thing is that the object comes first and the key comes second. Now, in my mind that's a little confusing, because in the dictionary you look things up with keys. And it kinda matches better with the literal curly brace notation to put the key first, but that's not what you do. And it's actually consistent with the name of this method which is Dictionary with Objects and Keys not Keys and Objects. The last thing to be aware is that it's a nil-terminated list when you create your dictionary in this way. And then, when you output it, although the keys and values are alternates in the list as I said. And when you output it you see something very similar to what we had before, the same dictionary gets created. There's one last way that's worth noting about how you can create a dictionary, and that's using a combination of two arrays and mapping them together. So in this case, I created one array called people and that has, an array is an ordered list with possible duplicates. So it's Don, Sandy, Julius, Theo, Joy, Martha, Coconut. And then, the second array is requests. And this is also an array. And it says tofurkey, burrito, chicken, hamburger, burrito, pixie sticks, kibble. So you can see there's a double there. But that's okay, cuz it's an array. And now, we're gonna create a dictionary out of that. We're gonna create a dictionary by using the method dictionary with objects and four keys. As a method that's being called on the NSDictionary class. And so, we're gonna pass it the requests for the objects and the keys for people. And the output that we get is what we would expect, same thing that we had before, we're constructing the same dictionary over and over again in different ways. I actually don't really like this style of creating a dictionary, and the reason why is twofold. It's kinda confusing for me. Like the previous one, in this case, you specify your objects first, and then your keys. That's a little bit counterintuitive to me, because when you find the data in a dictionary, you look it up by the key. The more troubling thing that I have with this approach is that, what you create the dictionary with is actually two arrays. And that's not really appropriate, because the keys act as a set. If you have a duplicate at array that you passed into four keys, you're gonna get behavior that you probably weren't expecting, because you shouldn't have duplicates. In an ideal world, four keys would fill would be past a set. But then, the problem is that sets aren't ordered, and so if you were gonna match each element of the keys up with one element of the array you would have to sue something that is ordered. So this is sort of a hacky halfway way of developing a dictionary. My prefered way is to use the @ literal notation if you can, if you're not creating the dynamic. So a quick self quiz. We've looked a lot of different ways that we can create literals with the at sign. Let's take a second and look through these as possible things that you might create. The first one says, if you have an at symbol followed by a number, what kind of object are you gonna create? The second one says, if you have an at symbol followed by quotes and with text in it, what are you gonna create? The third question is, if you have an at symbol with square brackets and a sequence of objects, what are you gonna create? And the fourth one is, if you have an at symbol with curly braces and object colon object comma object colon object, what are you gonna create? Four different ways that you can use the at symbol to create literal objects. Pause the video if you need to, we'll give you the answers in a moment. Last chance. Okay, so the first one creates an NSNumber. That is an object oriented way of representing a primitive number like int or float. The next one is the NSString. That's an object-oriented way of representing a char star, a string. The third one is a NSArray. This is also an object-oriented way of representing an array, which is also available to you in C, but with different syntax. And then, the third thing is an object-oriented way of creating a dictionary. And although it's probably possible to have a dictionary in C, I don't think there is a primitive dictionary in C. Quick quiz is over. How'd you do? 100% great. Once you have a dictionary, it might be helpful to know how to use it. One thing that you can do with it is you can select objects from it, and there are lots of different ways that you can select an objects from a dictionary, it's kind of intuitive actually. So in our first line here we are creating our dictionary and we are using the literal notation. A sequence of people followed by a sequence of things that they would like for dinner. In the first line, we use an NSLog statement with a format token of percent at to ask what does Theo want for dinner? And the way we find that out is we use the variable name dinnerRequests. We use square bracket notation, and instead of using an index like a number that we would have used when it was in NSArray, instead of asking with a number, we're gonna ask with a key. So it doesn't have to be a number, it could be anything that could be a possible key in your dictionary. And if that key is present in your dictionary, then the value will be returned. And so, in this case, we hope that gets returned. In our second line, we're gonna access our values in another way. We're gonna use a method called object for key. We're gonna use the receiver, is our dinner request object and we're gonna use the square brackets to do a message passing notation. And we're asking the object for key and the key that we're asking for is, what is the value for the key Joy? And if we look up there we see that better be burrito. In the third example, we do something a little bit unusual. We do a reverse look-up. So instead of asking for a value associated with a key, we're gonna ask for all of the keys associated with a particular value. Now, we know that there can only be one unique key of a, dictionary only has unique keys, they can't be repeated, but the keys can have the same value repeated over and over again. So it's possible, like in our dictionary here, that the burrito has showed up twice. And so if you wanna know all of the keys that are associated with that object, you can do the message all KeysForObject. We're gonna pass that into a local variable that we're calling burritowanters. And then, we're going to output that. We're gonna say these are the burrito wanters. We're gonna do a fast enumeration through that array. And each element of the array, we're gonna pass the description method to see which key was associated with that value. First one is almost the exact same id as an array selector. The second one is a message based approach. And the third one is really a reverse look-up. Typically, you don't do it in that order. And then, the output that you get, as we hope for, at least we hope this is what we get, the burrito wanters is an array of keys that we're cycling through. And we see that Theo wants hamburger for dinner. Good. That was our look-up. That's what we wanted. Joy wants burrito for dinner. That's good. That was our look-up. It's what we wanted. And then, these are the burrito requests, coming from Sandy and Joy. Yep, great, so we've got all the keys associated with the value burrito. Okay, terrific. So that's a way of selecting things from the NSDictionary class. Now, if want to cycle through all the elements in the dictionary, if you want to iterate through them, you can do a fast enumeration. But it's important to realize that if you do just a straightforward enumeration like this for id k in dinnerRequests, what k is going to be set equal to in each iteration through that loop is one of the keys in your dictionary. So k, because getting the related value's really simple, but that is the way in which you index into a dictionary, and so that kinda makes sense. So in this case, we go through each one of the keys intern within the iterator, and we output using a parenthesis and a comma in the text just to demonstrate that we are doing it a different way. And the output is what we expected, and again the order isn't preserved. Those keys can come in any order, we'll get all of them if we go through our iterator. If we go through our fast enumeration. But the order that you get them in is not guaranteed. Another way you can go through your NSDictionary is by values. And this is unusual, because dictionaries are really about looking up keys. But you can create an array of all the values that are in your Dictionary. So in this case, we pass dinnerRequests the message allValues, and v is gonna be a fast enumerator that goes through each one of the values. And then one by one, we're gonna print out which value we got through our iteration, and we're gonna ask how many Ts are associated with that value. We're gonna output that. And the result is this, that we find our that burrito is requested by two. Chicken, pixie sticks and tofurkey is requested by one. Burrito gets, because this is an array that you get back from all values, we hit burrito twice, and so we ask burrito again. We hit burrito once with Sandy then we hit burrito once when it's in there for Joy. And then, we output kibble and hamburger. Now, if you find yourself looping through values in a dictionary often, it's probably the case that you're not using the right data structure. You can do it occasionally, of course, you can if you need to, but the right way to go through a dictionary is on a key basis. You can also compare dictionaries. In order to be equal, two dictionaries have to have key sets that are equal for starters. The order doesn't matter, but the size and the content do. So not only must the have the same number of keys, those keys must all be the same. The key also has to have a value that's equal in both of the dictionaries. So dictionary one and dictionary two here, they have to have the white dots represent the keys, and the orange dots represent the values, and they both have to have the same number of keys. The keys have to have the same value, and each of those keys with one value has to be mapped to a value with an equivalent value. I'm overloading the word value, sorry. So in summary, an NSDictionary contains an unordered collection of key-value pairs. An NSDictionary has a unique set of keys, but the values don't have to be unique. And these keys are used like an index. The dictionary itself is used like an index. It's to keep track of a bunch of different things you might wanna look up that's associated with a given key. So we use the key to ask what is the data associated with the value, with the key. In an example, might be if you're keeping track of a budget user accounts, you might have the idea of the user be the key, and then you might have a custom object be the value. So that you can ask what is the data associated with user id 12345, and get back an object that has the name, the birth date, any records that you have associated with them. It's a very common way to use a dictionary. All right, that's great we still have to touch base on mutable sets in the future. But that's it for NSDictionary. [MUSIC]