Last active
July 11, 2022 20:30
-
-
Save lecuseasar/dde69a7bff2ef1fb54581a16e67fd581 to your computer and use it in GitHub Desktop.
In this task, you learn a bit about filters in Kotlin. Filters are a handy way to get part of a list based on some condition. https://developer.android.com/codelabs/kotlin-bootcamp-functions#5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** https://developer.android.com/codelabs/kotlin-bootcamp-functions#5 */ | |
fun main() { | |
/** | |
* In this task, you learn a bit about filters in Kotlin. | |
* Filters are a handy way to get part of a list based on some condition. | |
* */ | |
//? Step 1: Create a filter | |
/** | |
* In Hello.kt, define a list of aquarium decorations at the top level with listOf(). | |
* You can replace the contents of Hello.kt. | |
* */ | |
val decorations = listOf("rock", "pagoda", "plastic plant", "alligator", "flowerpot") | |
/** | |
* Create a new main () function with a line to print only the decorations that start with the letter ‘p'. | |
* The code for the filter condition is in curly braces {}, and it refers to each item as the filter loops through. | |
* If the expression returns true, the item is included. | |
* */ | |
println(decorations.filter { it[0] == 'p' }) | |
/** Run your program, and you see the following output in the Run window: */ | |
//? ⇒ [pagoda, plastic plant] | |
//? Step 2: Compare eager and lazy filters | |
/** | |
* If you're familiar with filters in other languages, you may wonder whether filters in Kotlin are eager or lazy. | |
* Is the result list created immediately, or when the list is accessed? In Kotlin, | |
* it happens whichever way you need it to. | |
* By default, filter is eager, and each time you use the filter, a list is created. | |
* To make the filter lazy, you can use a Sequence, which is a collection that can only look at one item at a time, | |
* starting at the beginning, and going to the end. Conveniently, this is exactly the API that a lazy filter needs. | |
* In Hello.kt, change your code to assign the filtered list to a variable called eager, then print it. | |
* */ | |
val eager = decorations.filter { it[0] == 'p' } | |
println("eager: $eager") | |
/** | |
* Below that code, evaluate the filter using a Sequence with asSequence(). | |
* Assign the sequence to a variable called filtered, and print it. | |
* */ | |
val filtered = decorations.asSequence().filter { it[0] == 'p' } | |
println("filtered: $filtered") | |
/** | |
* When you return the filter results as a Sequence, the filtered variable won't hold a new list—it'll hold a | |
* Sequence of the list elements and knowledge of the filter to apply to those elements. | |
* Whenever you access elements of the Sequence, the filter is applied, and the result is returned to you. | |
* */ | |
/** | |
* Force evaluation of the sequence by converting it to a List with toList(). Print the result. | |
* */ | |
val newList = filtered.toList() | |
println("new list: $newList") | |
/** Run your program and observe the output. */ | |
// * ⇒ eager: [pagoda, plastic plant] | |
// * filtered: kotlin.sequences.FilteringSequence@386cc1c4 | |
// * new list: [pagoda, plastic plant] | |
/** | |
* To visualize what's going on with the Sequence and lazy evaluation, use the map() function. | |
* The map() function performs a simple transformation on each element in the sequence. | |
* */ | |
/** | |
* With the same decorations list as above, make a transformation with map() that does nothing, | |
* and simply returns the element that was passed. Add a println() to show each time an element is accessed, | |
* and assign the sequence to a variable called lazyMap. | |
* */ | |
val lazyMap = decorations.asSequence().map { | |
println("access: $it") | |
it | |
} | |
/** | |
* Print lazyMap, print the first element of lazyMap using first(), and print lazyMap converted to a List. | |
*/ | |
println("lazy: $lazyMap") | |
println("-----") | |
println("first: ${lazyMap.first()}") | |
println("-----") | |
println("all: ${lazyMap.toList()}") | |
/** | |
* Run your program, and observe the output. Printing lazyMap just prints a reference to | |
* the Sequence—the inner println() isn't called. Printing the first element accesses only the first element. | |
* Converting the Sequence to a List accesses all the elements. | |
* */ | |
// * ⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66 | |
// * ----- | |
// * access: rock | |
// * first: rock | |
// * ----- | |
// * access: rock | |
// * access: pagoda | |
// * access: plastic plant | |
// * access: alligator | |
// * access: flowerpot | |
// * all: [rock, pagoda, plastic plant, alligator, flowerpot] | |
/** | |
* Create a new Sequence using the original filter before applying map. Print that result. | |
*/ | |
val lazyMap2 = decorations.asSequence().filter { it[0] == 'p' }.map { | |
println("access: $it") | |
it | |
} | |
println("-----") | |
println("filtered: ${lazyMap2.toList()}") | |
/** | |
* Run your program and observe the additional output. As with getting the first element, the inner println() | |
* is only called for the elements that are accessed. | |
* */ | |
// * ⇒ | |
// * ----- | |
// * access: pagoda | |
// * access: plastic plant | |
// * filtered: [pagoda, plastic plant] | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment