Intro to Elixir | Lesson 9: Maps, Structs and Keyword Lists
ElixirTranscript
English (Auto-generated)
Hello friends and thank you for continuing the elixir learning journey with the series. Today we're going to learn about new data structures. We're going to learn about maps struck's and keyword lists. Let's dive right in. So maps are the primary key value storage in elixir. So in most programming languages to have a data structure where you can refer to the value using a key rather than using an index. So for example, we told you in a previous lesson that if you use a tuple, which is an ordered list of element or a list, also an ordered list of elements. We explain the difference before then That we uh refer to the value to the item by its location, usually from the start of the list of the tuple and then you go count 123 based on the index of the element with maps basically you refer to it by its key. So keys and maps can be any type most likely most commonly I would say it's atoms or strings. Okay. Um and values can also be anything. This is what makes electoral maps very convenient and very flexible. You can use them for a wide variety of things. If you're familiar with javascript objects are very similar to javascript objects in ruby hashes I believe in python. They're called victories, hash maps in java similar other structures and so on. So here is how we define a map and he looks at her. So if you find a map here by um using this duct which is percent signed curly brackets And then if I say something like name john smith and age 15. So it just defines a map with two key value pairs. The first key is named actually, you know what just about confusion for now, at least before I explain about atoms, I'll just use the strength. So and then you use the syntax here which is borrowed from ruby really, which is what we call hash rocket. Um it's mapping the key name to the value john smith in this case it's mapping the key age to the value 15. So let me go and I e x and experiment with this a bit. So I have my map which have to keep value pairs. I notice here how when it displayed it, it didn't respect the order that you entered it in. So that's one thing to keep in mind that the order may not be what you expect in maps. So it doesn't always respect the order that you created with. So we will see this in contrast with the keyword lists where it does respect the order. So in this case here my map is our map and then we can access using the square bracket page or my map and then square bracket name. We could access these values think syntax. So let me just copy these to put them in your notes. Uh and then here I can say we can access the values using the square bracket syntax look as in, you know, when I'm putting this year, I'll use io dot boots because if you're executing this safe from, you know um from elixir directly rather than I ex you will need to have io dot puts in order to display the value in in I X. We don't really need to do this. So we could just simply do uh something uh you could just do my map page which will just give you the value of it or if you can use I. O. Ports which actually returns the atom. Okay, so um it's most common to um use atoms. So atoms think of them like constant. The value of that constant is basically the name of the atom itself. So um atoms are defined using um a Colin before the name of the atom for instance we can have an atom apple or we can have an atom. Okay and so on. Um they are most commonly used as return values usually and tools. I mean notice here like when I did I'll put it did return um Okay as an atom so did return to me this. Okay as an atom when I did I Oh um but in many cases we do something like this we do something like error. Let's see there is an error message. And then the error message for instance, you know, invalid input. So it's very common to return a tuple whose first element is an atom and then the second element says the string or it could be another atom just telling you what the error is. So this is here in, especially in web apps is very common. But even in just a little extra libraries you will see this pattern of behavior extremely common. Um also it's very common to use items as keys to maps. So the map I just defined earlier, I could just redefine it differently as my map and then I can put something like name, I mean you could use the full, the full and I could do something like name and then hash rocket, I'll put um John Smith and I can put edge and then whoosh rocket 15 which can be shortened to a syntax that you may be more familiar with which is using, you know what you might call it the Jason syntax or if you're familiar with javascript objects very common in javascript or if you're familiar with ruby hashes also uses this syntax as well and if you do so meaning using atoms as keys. You have a nice syntax sugar to access values. How do you do this? Well, you know I owe that butch my map dot name and you do my map dot h. So let me show you this right here. So if I go to my ex and I put my map, I put my map and now I put that age you get the value here and then I put my map dot name where you get john oh I misspelled smith here. So it's mint so I should fix the tear. Um so this that's why you know, I would encourage you if possible use atoms as keys to your maps. Sometimes you could, I mean you could have anything just to show you here. Um for instance you could have mhm um Oh I guess you know, you could to create a new map that have a new key value pair. You could use the put method in the map module which is built into the lecture. So I can say my map here and let's say I put something like one as a key and in the value say hello, I notice here is the key is the number one and then the value is the string Hello? Uh the key can be anything just to reiterate that fact there that said it is most common to use atoms. And I would encourage you whenever possible to use atoms for your for your keys in elixir, elixir maps. Um Now just not on the syntax, this is a very special syntax for maps, if you're coming from an object oriented programming um language you're probably used to calling methods on objects using that notation. So this is very reminiscent of calling um methods on object but it is not the case in a lecture and the lecture we call functions and the way we do it we usually have module dot function. like what you, what you saw me do here is basically, you know, mapped output. And then I put the map and then I put the key and then I put the value in an object oriented programming language. You probably use it something like insert something like this. A and then you know, let's say one and then hello, you would probably see something like this. These patterns you will not see in a lecture due to the immutable nature of the language. So again, just be careful here where it's just think of it like a syntax sugar to access the value of of of a map. Um So uh the pattern is what you see right here, module that function and then you pass in the details, the details to it. All right. So these are maps in a nutshell. And again here, uh you know, just I'll add this for your note, you could use the map library. Uh that is built with elixir to perform functions on elixir maps. So in here, if I do map dot and if you hit tab it will tell you all the functions that are available on the map module. So in this case you can see yet pop split etcetera. Just remember you're always making a new map when you're making computations because of the immutable nature of of elixir and uh in the next lesson we're gonna encounter the venom library, which is a very powerful library that works on maps and it works on less than many others. Uh it's deserved, it deserves its own lesson so we'll leave that for later but for now use the map um library when you want to perform some actions on elixir maps awesome. So taking our maps to the next level, we could use trucks or trucks. Our trucks are used um if you know, if we want more control over key value uh structure, I should say data structure. We can use, we can use uh strikes that enforce uh the presence of certain keys. So how do we do this? Well stay here. I define uh you start usually defined as struck by defining a module. How would say you know structures are probably the closest to what you might see in an object oriented programming language. So they're very handy. Wouldn't say you're connecting to the database or when you want to define um you know some predetermined key value storage but do you want to enforce it a little bit more than what you see in maps. So let's say I call it something like a person and then what you do here is you do deaths trucked and then you put something like name, empty value, Age 15, something like this. So let me go ahead and uh define this uh structure right here. So what happens is it gets compiled right here um after this uh we can we can use the structure similar to how we use a map. Yeah. Um, for instance, I say for example, J equals person and then so notice here, I use the percent sign and the curly brackets, but in between them I put this truck name which is a module name that contains this destruct definition within it and then I can say something like name. I put john smith. All right. So let me go and try this in um, in here. So look at what happened right there. So first of all it find this person here, which is a construct that is the person module and then it automatically added the age 15. The reason being is we added a default value for age being 15. The default value for name is an empty strength, but because we've defined the name and here it overrode the default value. So name here is john smith while ages 15, so I p J dot age J name and then basically you access those values from this truck. There are few other features to destruct, but this is really the basics of it is defining what attributes you want to except for the struck. Now to show you here is if I want to try, let's say to put city and put something here will actually throw an error. It'll tell you city not found. Remember in maps, you can just randomly put key value pairs, but when you're actually using structure, it would enforce what keys you're able to assign to your, your struck to your, you know, I'm abstract. Let's call it or it's called a tractor I guess for, you know, to make it clear but it is a key value storage with some enforcement for example, you know, you could have other features such as enforcing certain keys exist that you have to set them and so on. But for the most part, it's really as simple as this is defining a module that behaves like a map that enforces the only things that you could have in it is certain things, so it makes it uniform. Let's say you want to connect to a database. Those uh huh. The fields that connect to the database. Our only the columns in the database. So which means that you cannot for example, assign a column that is not in the database. You can have virtual columns depending on the library that you have. But you know, that's again an example for how you would use a struck. Now, lastly here we have cured list. Secured lists are basically uh lists with extra features. So it behaves like a key value storage or should a great story key value data structure. Um you know, but it's a list at the end of the day. Okay. It's common in programming languages or I should say in functional programming languages to have lists like this. Okay, so I'll write some extra code here. But you know, this is common in other languages and we'll see how this turns into a cured list. So for example, I can say my list is a list that it's a list of two poles. So it's common to have a list of two poles. So the tuple, let's say the first element is an atom. Second element is, you know, you see a number in this case, could be any value, The 2nd element is and adam third number is a number. Now, remember lists are very valuable in functional programming languages because the list is composed of a head and a tail. The tail is immutable, which means you can have many things referring to it, many variables referring to the same tail. Uh, and it wouldn't make a difference because we're not going to mutate it. And then we simply construct a new list by having an element added to the beginning of the list. That's why if you recall against more of a review for the list lesson is if I have something like this, basically I have head of the list and then we use the pipe, uh, the pipe notation and then tail and then we have this. If you recall head will just be a tuple that is this first couple a one. Now tail will be actually a list that have the uh, second thing to notice here is already written in a bit of an interesting way where it's written as if it's a key value storage because if you write the list in this particular format, it does behave like a key value storage. Okay, so key value storage, meaning that um so for example here my keyword list equals, I just based this one right here, notice that I have now what it's called a keyword list. Now if I want to check the type of it, my keyword list, it is actually a list. So this is why this is list my keyword list actually returns through but this behaves like a key value storage, meaning if I do my keyword list and I tried to do that A I'm sorry, I do have to use this syntax here. Uh then I actually can access the value which isn't really easy to do with the list. If you remember in normal list with Alexa, you have to traverse the list one item at the time, which means that um it actually gives you this convenience. So um and similarly here, b and then if I try see it'll give me NELL because that doesn't exist. So notice how I turned the list in a way that behaves like a map behaves like a key value storage, but it is a list at the end of the day, while for example, if you remember my map here, the fire type is list. Maps are not lists, maps are actually maps they have their own data structure. So it's map my map and you get. So what is the difference you may be wondering what's the difference? Well there's some key differences here differences I should say not just differences. Key things story to to note for keyword lists. Order matters in key or list basically things are stored in the in the order you create them at. So in this case not necessarily call with my map. I I started name age but it put a first displayed age first anyway so order we shouldn't rely on order for maps if we care about the order of things in a particular list then um uh then what we have to do is probably you could pick to use a cure list and then hear keys are always atoms. So if you want to turn to listen to a cure list you have to have the kisses atoms. Um By the way you could use a short syntax here. So I just want to write it here before I forget. So p. B. two. So this gives you the same thing. So these two are actually the same effect basically if you so this year is the same syntax. Look at you the same results I should say as as as this one. So these two are equivalent are the same. Right. Better thing to not hear uh keys can appear more than once. Okay so because it's a list you could just traverse the list which means a key can appear more than one. You should be careful if you're trying to access it or to use it purely like a like a map. Because what happens is let me let me show you here. So if I put here my cure list I just call it K. L. Equals let's say A one B two and then I say I use a again as three if I try K. L. And then and bracket adam A I get one. So notice it picks the first one that said This basically is still a list that have three two pills and the last one is a three. Okay now maps work differently. So let me try to do the same thing as a map. So let me try to do a 1 B2 and then a three. What happens that will get a warning? It will say Kiai will be overridden in a map or does it actually picked the latter version of a which is a three here. So which overrode overrode this a one. So map kik in maps can only exist one in cured list. It can exist multiple times as many times as you wish with. So that's why you'll notice those are both used in a variety of circumstances. If those kind of use cases fit your scenario than you would pick your lists that said, you know, I I tend to see maps used a lot more widely. They're more flexible, especially that you could put anything in the keys and um yeah, there, you know, but all these data structures are useful and and and popular to use in like so thank you for listening to me and I will see you in the next lesson.