Advanced Collection Operations in Kotlin

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This is so clean and well made. I already use most of these functions but I still learned a lot.

πŸ‘οΈŽ︎ 6 πŸ‘€οΈŽ︎ u/sellithy πŸ“…οΈŽ︎ Jun 12 2021 πŸ—«︎ replies

Seb's videos about the stdlib are just the best! Absolutely love them

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/Raph0007 πŸ“…οΈŽ︎ Jun 13 2021 πŸ—«︎ replies

Why didn't he use a kotlin worksheet for this?

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/IsuruKusumal πŸ“…οΈŽ︎ Jun 13 2021 πŸ—«︎ replies

Where are your other episodes ?

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/Accomplished_Ad_1740 πŸ“…οΈŽ︎ Jun 12 2021 πŸ—«︎ replies

Did you speed up your typing in this video?

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/lesincs πŸ“…οΈŽ︎ Jun 13 2021 πŸ—«︎ replies
Captions
today we are learning about advanced collection functions that we can use to work with and manipulate all kinds of kotlin collections my name is seb i'm your host and you are watching kotlin standard library safari [Music] before we dive into the nitty-gritty of advanced collection functionality let's warm up a bit and let's have a look at a selection of functions that allow us to check conditions for our collection elements they're called any none and all each of them takes a predicate so a function that returns true or false and checks whether the collection fits this predicate let's say we have a group of friends which really are just a collection of people with a name and maybe a driver's license when we want to check if the group can travel by car we want to check if any of them have a driver's license so we use the any function why because any returns true if there is at least one element in our collection for which the predicate returns true as another example let's say we want to check if this group of friends is allowed to enter a club for this we would need to make sure that none of the folks in the group are under age so somewhat unsurprisingly we use the none function here which returns true when there is not a single element in our collection that holds true for our predicate makes sense it ensures that none of the elements match the third function in the bunch is the all function at this point you can probably spot the pattern all returns true if each and every element of our collection matches our predicate now before we move on here's a little brain teaser what about empty collections let's look at any first well there is no element that can satisfy our predicate so it returns false the same goes for none there is no function that can violate our predicate so it returns true that also seems fair enough but what about all well maybe somewhat surprisingly this one returns true on an empty collection regardless of our predicate and while that may stump you in the first second this is quite sound because you can't name an element that violates the predicate therefore the predicate has to be true for all elements in the collection even if there are none this might feel a bit mind-bending to think about at first but you'll find that this concept which is called the vacuous truth actually plays very well with checking conditions and expressing logic in program code alright with our brains freshly teased let's move on to the next topic and look at how we can break collections into parts if we have a collection that just contains a bunch of items we can cut up the list into individual chunks of a certain size by using the chunked function what we get back is a list of lists where each element is a chunk of our original list let's look at an example to visualize this let's assume we have a collection of a bunch of objects we're just representing them with emojis here now we break this list apart with a chunk size of three and have a look at the resulting collection the first element in our result is in itself a list which contains our first three objects the plant the rocket and the light bulb the next element is once again a chunk and contains the three elements that follow after that the penguin the gear and the robot the only chunk that might not contain three elements in our case is the last one simply because we ran out of elements to fill another full chunk with so in this case the last element of our resulting list only contains the book stack in typical standard library fashion the chunked function also provides a little bit of extra power if you want to immediately transform the chunks we just created we can apply a transformation function for example we could reverse the order of elements in the resulting lists without having to do another map call separately so to reiterate the chunked function cuts our original collection into lists of lists where each list has our specified size somewhat closely related is the windowed function it also returns a list of lists but instead of cutting our collections into pieces of the same size it gives us a sliding window view of our collections let's look at the same collection of emojis again and this time called windowed with a size of three the result of this call once again starts with the first three elements planned rocket light bulb the next window and here's where things are different from the chunked function contains the rocket the light bulb and the penguin so instead of cutting it up into discrete chunks we simply moved our window of size three over by one which includes some overlap the window function can also be customized further apart from the window size we can also adjust the step size so the number of elements that the window should slide along at each step this is set to 1 by default but we can increase it as we'd like we can also control whether our results should contain partial windows which changes the behavior when we've reached the end of our input collection and we're running out of elements with partial windows enabled we just keep on sliding and we get the last elements trickling in in the form of smaller windows until we get a window which once again only contains the last element from our input collection the book stack and as the cherry on top you can once again squeeze in a transformation at the end which receives the individual windows so the result of those functions were a bunch of nested collections but what if we want to unnest them you know we might want to turn these collections of collections back into just flat lists of elements well as usual we do not need to fear because the standard library has got us covered we can call the flatten function on a collection of collections and as you may suspect the result is a single list of all the elements that were originally contained inside our nested collections and while we're already on the topic it makes sense to also give some consideration to the flatmap function flatmap is like a combination of first using map and then using flatten it takes a lambda which generates a collection from each of the elements in our input collection so in our example the function that we provide creates a list for each element of our input collection containing the letters of the original strings then the nested connection once again gets directly flattened so that we end up with just a plain list of elements or in our case the characters in the names so whenever you're generating an operation on a list for example which in turn generates collections for each one of your elements consider if flatmap can help you simplify your code alright let's take an even further step because so far we've pretty much always just looked at a single collection and what we can do with it or do to it or do about it let's talk about how we can combine two collections and create a new one from them and i'm not just talking about the plus operator used to concatenate two lists that one you've probably already seen i'm talking about zipping which solves a somewhat particular use case let's say we have two collections and the elements at each index are somehow related for example we have a list of cities in germany and we have another list of german license plates that correspond to those cities by zipping these two collections we get a list of pairs where each pair contains the elements with the same index from the original two collections you can imagine this just like a zipper on a jacket where the teeth match up one by one so we kind of zip together the elements of our collections and we get pairs in our case of the city and the corresponding license plates the zip function can also be called using infix notation for that extra bit of flair though it behaves the same also i think it may be a bit of a theme or a pattern at this point but guess what zip can also take a transformation function once again we pass a lambda that receives the values of the individual zipped pairs and we can do some kind of modification to them the standard library also contains the inverse function called unzip which takes a list of pairs and splits them back into a pair of two separate lists i'm using a destruction declaration here to access them both i think this is also a good point to mention the zip with next function here instead of zipping together two separate lists element by element this function takes one collection and zips each of its element with the one that follows in a way zip with next is really a specialized case of the windowed function we already learned about today for example say that we have a bunch of numbers and want to check the change so how much the numbers increment or decrement in each step we can express this quite elegantly using zip with next where the function always gets a pair of one number and the one that follows immediately after three and one one and four four and one and so on before we wrap up let's round this episode out with a grand finale i want to introduce some functions that help us build custom aggregations let's set the scene with a small callback in the last episode we learned about functions like sum average count and functions to receive the minimum and maximum elements inside a collection all of these reduce our collection to a single value on the off chance that you missed the last episode make sure to check it out right here on the channel and give your memory a quick refresher now we might have a similar use case but may find ourselves in a situation where there's no out of the box function for it for example we may want to multiply all numbers in a list instead of summing them in this case we can rely on the reduce function as a more generic version for aggregating a collection we call the reduce function with a lambda block which receives two parameters a so-called accumulator with the same type as our collection elements and an individual item from our collection all the lambda needs to do is return a new accumulator the key point that makes this reduce function work is that each invocation one after the other receives not only the current element but also the result of the previous calculation inside the accumulator let's talk a bit more about that the function starts with the first element in our collection in the accumulator then it runs our operation in this example we multiply the accumulator which is the first number with the current element which is now the second number with that we've calculated a new value which will again be stored in the accumulator and used when our function is called once more with the third element and so on we continue to gradually build up the final result in our accumulator one might even say we're accumulating that result once we've gone through all the elements in our collection reduce returns the final value that's inside the accumulator so as you can see with reduce we can hide a lot of mechanics for aggregating our collection behind one function call and stay true to colin's concise nature but we can actually go beyond this and take this versatility one step further with the fold operation remember when we used reduce the iteration starts with the first element of our input collection in the accumulator with the fold function we get to specify our own accumulator and in fact it can even have a different type than the items in our input collection so say for example we have a list of words and we want to multiply the number of their characters together we can do this using fold the underlying mechanism is the same our function gets called with an accumulator and a value the difference is that this time we specify the initial value and type of the accumulator ourselves by the way note that we pass one as an initial value for our accumulator and not zero that's because for multiplication one is the neutral element had we actually used zero in its place our whole calculation would have been zero times five times all the other following which would have always ended up being zero both fold and reduce come in a number of other flavors as well the sibling functions reduce right and fold right change the order of iteration and reduce or null allows you to work with empty collections without throwing exceptions note by the way that fold does not throw an exception on empty collections in any case it will just return the initial value of our accumulator that we provided directly and then there's still the functions running fold and running reduce these don't just return a single value representing the final state of the accumulator but instead return a list of all the intermediate accumulator values as well for more information on these functions you probably already know my suggestion by now have a look at the official documentation which you can find on kotlinlang.org phew that was quite a selection of collection operations more topics will come your way in the next episode so you know what to do find that like button hit the subscribe button and ring that bell for now i suggest you go and explore what you've learned today maybe you can find a point in your code where a predicate some zipping chunking or windowing could come in handy or maybe you want to explore with defining your own aggregation functions based on the reduce or fault functions we learned about today but that is up to you because i am signing off and i hope that you will go and explore some more kotlin take care see you in the next one [Music] you
Info
Channel: Kotlin by JetBrains
Views: 7,510
Rating: 4.9628253 out of 5
Keywords: Collection operations, Collections, Kotlin, Functional programming, JVM, Standard Library Safari
Id: N4CpLxGJlq0
Channel Id: undefined
Length: 12min 19sec (739 seconds)
Published: Sat Jun 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.