<v Instructor>The first of our functional methods</v> is called Map, which let us map a function over an array of elements. As with the other functional methods we'll be talking about, filter and reduce, map is often a good replacement for looping, as we'll see in this section. Let's start with a statement of the problem we want to solve. In this section, we're going to take an array of the names of four US states, and we're going to convert that array into an array of strings where each string is appropriate for use in the URL. So let's take a look at what I mean by that. All right. This is what our initial array will look like. We pick four US states for brevity, but obviously this could be generalized to a full list of states or indeed any array of strings. This is just for concreteness. So, let's say, our states are equal to, go for some midwest states: Kansas, Nebraska, North Dakota, and South Dakota. So what we wanna do is convert a string, like Kansas with a capital K to lowercase. And we want to do something like this with North Dakota. We're going to convert that to lowercase with a hyphen. Oops, the editor got too smart there. All right, so let's solve this using the tools we currently have. We'll create a function that takes in this array of states and returns the appropriate URLs. Like this. As with the programming examples we've seen so far in this tutorial, this part of the program will consist of the sequence of commands telling the computer what to do; a style known as imperative programming, which is why we say this is URLs imperative version. Call it imperativeUrls, and it takes in an array of elements. So it's called elements. And so this is our strategy. What we're going to do is, for each of these elements, that just sound familiar for each, for each of these elements, we're going to convert it to this format here. So if you look at this, what that involves is converting it to lowercase and then converting any spaces to hyphens. My preferred way to do this is to split it on whitespace and then join on hyphens. So let's take a look at the REPL, and see how that works. This is a good example of how to use the REPL and to file in combination. So we can look at a string like this, actually let's copy it here. Take North Dakota, and we can convert it to lowercase using the toLowerCase method, like that, and then we can split it. Now, of course, if we could split here on a space, that would work, like that, and then join it on a hyphen. This gives us the kind of URL we're looking for. North Dakota. Just to clarify, this is the kind of thing that you could put into URL. Example.com/. You couldn't do this: example.com/North space Dakota is no good. But you could do example.com/north-dakota. So, just to clarify that, and then I'll delete these for now. So you can see though, this is how we get that form, but I actually prefer a slightly more robust way of splitting, as I mentioned before, which is to split on whitespace. Remember, we can do this with a regular expression. Whitespace backslash s and one or more of them. So it's the same thing. This is nice because now we're robust to things like this, oops, there's a second space. Still gives us the same result though. So what we're gonna do is go through this list of elements, and for each one, we're going to convert it to this URL-friendly form. And then we'll add it to an array that we then return. So let's call that array urls. And it will start as an empty array, like that. And then for each element, we'll convert it to the right form and then we'll push it to this urls array. So we can say elements.forEach. So elements.forEach(element), remember, I like to ignore the word "function" just when I say it to myself. And then we can use the push method to push on the URL version of the element. We got it here. Actually didn't wanna copy this semicolon there. That's fine. Element.toLowerCase.split on whitespace .join on hyphen. And then we want to return the urls. So this is a pretty good example of reading code. This isn't very long. There's nothing here that we haven't seen before, but it puts things together in a new way. If you had any trouble with any of the steps here, I recommend going step by step and using a console.log statement to trace the execution of the program. But for now I'll just call console.log on the result of calling this function on our state's array, like this. So let's think about what this should do. We put states into here. So this elements array is states.forEach(state), and then we'll push the lowercase version join on hyphens. So this should be Kansas, Nebraska, North Dakota, South Dakota, where they're all lowercase and these spaces are replaced with hyphens. Let's see if it worked. And there we go. Look at that. All right, this is an excellent example of an imperative program. Step by step, urls equals empty array for each element, push on this thing, and then return the answer. Notice that it uses what we've previously identified as mutation. We start with this empty array and then we mutate it by pushing to it before returning the result. Now we're going to look at a way of doing the same thing without mutation. We're gonna take in the states array and just directly return to the thing we want. The way to do that is with map. So let's take a look at the REPL to understand what's going on. Let's start with a slightly simpler example. Let's start with an array of numbers. 1, 2, 3, 4, and supposed we wanted an array representing the square of each of these numbers. So 1, 4, 9, 16. We could do that using map, like this. We say map and then we'll map over an anonymous function. Kind of like the one we put here, it's a function without a name. It takes in one argument, which is each element in turn, let's call it n, and then open curly brace. We don't need any new lines. We can just put them all in one line, return n times n, which is n squared. There we go. So what map does is applies this anonymous function to each element in the array and then returns the result. Now you may recall from chapter five, that we can also define functions using the fat arrow notation. Let's review that. Instead of function, we can just say n as an argument and then fat arrow return n times n. You can see that's the same result. Now it turns out that JavaScript allows us to simplify this even further when there's only one argument like this. We can actually get rid of the parenthesis, like this, and we can even get rid of the curly braces and the explicit return, like this. This is a really nice compact way to convert one array into another, by mapping over this anonymous function. Now let's go back to our file to see how this idea applies to mapping the URL function over the array of states. We'll make another function called functionalUrls. This is just for convenience. Just so we have something to call. Same thing, takes in an array of elements. So think about what we want to do here. We want to map a particular function over these elements. So the way we do that is to take the array, call map, and then give it the anonymous function. In this case, the array is called elements, map. Instead of n, we'll have elements, fat arrow, and then instead of squaring, well, we want to lowercase it, split it on whitespace, and then join it on hyphen. But that's exactly what we have right here. It's just the argument of push. But if we look at this, this is just the exact array that we want. So we can just return it. So now we can call functionalUrls with states. And we get the exact same result. This is a common theme in functional programming. Oftentimes, you can take something like this that has a bunch of different lines and condense it down to just one line. Return elements.map, and then this stuff. As a final step, we're going to take this stuff and factor it into a separate function. We'll call it urlify, which is to say, it takes in a string and returns a URL version of that string. Example: North Dakota with a space and caps becomes this. Takes in a string, and returns that string with this stuff here. String.toLowerCase.split on whitespace .join. And it just returns that. So here, instead of pushing this thing, we can do this. Return this here, so this pushes the urlify version of the element. Just double check that, make sure it works. Good. And then in here... Boom. So it's working just like it was before. We factored out this common operation, which converts a string to the URL-friendly version. And you can see just how compact the functional solution is. This is one of the reasons I love functional programming. If you can figure out a way to solve a problem with functional programming, often, it's just a single line. It's conceptually simple; it's compact. And once you learn how to use it, it's really easy to read and it's easy to maintain. And you'll note that there's no mutation here. We didn't modify anything. In fact, we don't even have the local variable, this urls array. We return the exact thing that we want. We just map this function, urlify, over the array of elements. Now oftentimes it's easier to make the imperative version. So one of my favorite techniques, as I'll discuss briefly later in this chapter, is to first write a test for the functionality that I want, then write an imperative version that gets the test to pass, and then write a functional version and make sure the test still passes. With experience though, you might find yourself going right for the functional solution, which, as we can see, can often be condensed down to one line.