Hello. In this section we'll learn about transforming collections. Transforming a collection means to produce a new value. Usually a collection, but it could be some other type of value that is based on the elements in the collection. Probably the simplest way to transform a collection is by using the map method. map takes a function which is used to transform the elements and returns a new collection containing those transformed elements. So for example, if we have the list 1234 shown here and we call map with a function that adds one to each element. The result would be a new list containing 2, 3, 4, 5. We can do the same thing with array buffer and with Map. Note when we call map on a Map, the function takes two parameters, the key and the value. And you must return a tuple which will be the values that make up the new Map. Note that after calling map, the number of elements is unchanged. For sequences like lists an array buffer, the order of the elements is also unchanged. flatMap is the next method we'll look at. One way that flatMap differs from map is that allows us to change the number of elements in the collection. It does this by allowing the function that we passed a flatMap to return a new collection and the result contains all of the elements in the collection that's returned. So for example, to remove all the elements from a list, we could do as shown in this example here calling flatMap with a method that returns an empty list. This will produce a list with no elements as a final result. In the next example we're doubling the number of elements by returning for each element an ArrayBuffer that holds two elements. The first element is original element and the second element is double the original element. In our final example we're keeping the number of elements the same but we're changing the type of the key converting keys from numbers to strings. To further illustrate the difference between map and flatMap we're going to implement a program that returns all of the phone numbers within a contact list. Our data structure for contact is as shown we have a contact which is a name and phone numbers which is a list of string and then our contacts is simply a list of contact. If we use map to do this, say by returning the phone numbers from each contact, we'll end up with a list containing lists. This is not what we want. By using flatMap instead of map, we can flatten this list of results so that we only have a single list containing just phone numbers rather than a list of lists. That's what we do here, flatMap with the same function as before and now the result is just a list of phone numbers. The next method we're going to look at is called foldLeft. One of the ways in which foldLeft differs from flatMap and map, which we've seen previously is that foldLeft allows us to transform a collection into any other type. flatMap and map, on the other hand, can only return a collection as a result. On this slide, we have three examples of using foldLeft. In the first example here we're summing up the elements of the list. In our next example we're reversing a list and in our final example we're returning true if the last element is even or the list is empty. As you can see, foldLeft is very versatile. In fact, we can implement any transformation on the collection by using foldLeft. As a result, foldLeft was a little bit more complicated than flatMap and map. So we're going to take a few slides to explain what's going on. Firstly, we're going to explain this curious thing you might have noticed. foldLeft actually has two parameter lists here. The first parameter list is a zero, an integer, and the next parameter list is a function. Let me see that pattern in the other examples. Empty list and a function and true and a function. So we need to understand that detail. Once you've understood that will move on to explaining how foldLeft works and we're looking at from two different ways. Hopefully by the end of this, you'll have a good understanding of foldLeft. The first step in explaining foldLeft is explaining methods that have multiple parameter lists. This is an unusual feature of Scala but there's not really a lot going on here. Methods can be defined with multiple parameter lists as shown here, we have two parameter lists. When we call the method, we must pass parameters in the appropriate parameter list. So here one parameter list, another parameter list. We do that in the usual way using parentheses or we can use parameters in curly braces if we want. In the first way of understanding foldLeft, we're going to think of foldLeft as working with two values. The first value is an accumulator which represents the value we've computed over the elements so far. The second value is a function that tells us how we update the accumulator when we see a new element in the list. These two values correspond to the first and second parameter to foldLeft respectively. So in the example here we're summing up the elements of the list. Our initial value for the accumulator is zero. This is saying that the sum of the elements of an empty list is zero, which seems reasonable. The function here which updates the accumulator tells that when we see a new element in the list we add it onto the accumulator. So the accumulator is a running total and this again makes sense. Taken together, we can use this to understand how foldLeft is working. We start some initial value to the accumulator and then we update the accumulator according to this update function. In the second way of understanding foldLeft, we're going to think of foldLeft as taking a list that is constructed from right to left and restructuring from left to right. We're going to replace nil the empty list with the initial value of the accumulator and we're going to replace the prepend operation, which is the primitive way of constructing a list with values from the update function. To understand this, we need to go back to how lists are constructed when we call the vararg a constructor as shown here. This is hiding from us some of the details of how this is built. Well, this is actually built using this double colon, prepend operation and it goes from right to left. We start with the empty list nil and then we put three onto the front of that. There we put two onto the front of that and then put one onto the front of that. So the list is built from right to left, putting brackets in makes this explicit, prepending three on two nil, prepending two onto that resulting list and then prepending one onto that, continuing the second way of understanding foldLeft. We're going to define this function add which adds together two numbers and then use it in a call to foldleft as shown here, we have add as the update function zero as initial value of the accumulator and we're calling it on the list 1, 2, 3, nil. We're writing out the list explicitly here so that we can remember its structure and what we're doing with foldLeft is starting with the initial value of the accumulator instead of ending with the nil empty list and then using add to combine the elements in the list where we would have had that double colon prepend operation and we proceed from left to right so we can see that fold left goes from left to right, starting with the initial value of the accumulator and combining with the update function. Whereas the list is built from right to left. Starting with nil the empty list and combining elements with the prepend operation. We can extend this understanding of foldLeft to the general case where we have a list with an arbitrary number of elements. So calling foldLeft with the initial value of the accumulator, Z or Z if you're an American and an update function, f is equivalent to calling f with that initial value of the accumulator and the first value in the list and then combining the partial results with successive values in the list, going from left to right. The explanation for foldLeft that we view so far have all assumed we're working with a list. However, we can generalize these explorations to any data structure as long as we can assume some order on the elements. This order can be well defined as it is in a sequence or it can be arbitrary as it is in a Map. Let's work with an array buffer here. We can construct an array buffer as shown on the slide array buffer 1, 2, 3. And we can think of constructing this array buffer as prepending elements onto an empty array buffer as shown here, we start with the empty array buffer and we prepend three and two then one. This is exactly the same way in which we could construct a list and therefore we can transform the explanation we just gave for foldLeft on a list to apply to an array buffer, straightforward way. The final transformation function we're going to look at is called groupBy as the name suggests groupBy groups the elements of a collection. It does this by using a function which is called the partition function and the groupings are determined by the value of the partition function. Each value of the collection that has the same value for the partition function will be grouped together. Make that a little bit clearer with an example. Here we have some emails and as you can see, there are two different domain names that we have this scala domain and we have earth.world and we want to group our email addresses by domain. So we're going to create a function that returns just the domain, which will be our partition function. So here we give an email address and we drop everything before the @ sign. So given this, we can call groupBy and the result, as we see here returns emails grouped by the domain names. And that is it for the transformation methods. We've seen the following methods for transforming collections, map, which just transforms the elements, were keeping the general structure of the collection the same flatMap, which can transform the elements and the structure, but still gives us a collection of the same type, foldLeft which can transform a collection in any way and groupBy which partitions the elements using a partition function.