Skip to content

Instantly share code, notes, and snippets.

@lecuseasar
Last active July 11, 2022 20:30
Show Gist options
  • Save lecuseasar/dde69a7bff2ef1fb54581a16e67fd581 to your computer and use it in GitHub Desktop.
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
/** 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