Kotlin Collections: Getting Started | raywenderlich.com

In this tutorial, you’ll learn how to work with Kotlin Collections. You’ll transform data, filter it out, and use different types of collections in Kotlin!


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/4131729-kotlin-collections-getting-started

Hi Fill.
I have been fowling your tutorial on Collections and using https://play.kotlinlang.org Playground.

The Transforming Data section’s code works fine but Filtering and Grouping returns an address or something and not the data. Am I doing something wrong?

package operations

data class Product(
val id: Int,
val name: String,
val price: Double
)

class Receipt(
val id: Int,
val seller: Worker,
val products: List,
val isPaid: Boolean = false
)

class Store(
val receipts: List,
val workers:List
)

data class Worker(
val id: Int,
val name: String
)

fun beer() = Product(id = 2, name = “Beer, light, 0.5l”, price = 7.5)
fun coffee() = Product(id = 3, name = “Ground coffee 1kg”, price = 5.0)
fun bread() = Product(id = 1, name = “Gluten-free bread, 1kg”, price = 5.0)

fun main() {
val firstWorker = Worker(id = 1, name = “Filip”)
val secondWorker = Worker(id = 2, name = “Chris”)

val store = Store(
    receipts = listOf(
        Receipt(
            id = 1,
            seller = firstWorker,
            products = listOf(bread(), bread(), bread(), coffee(), beer()),
            isPaid = true
        ),

        Receipt(
            id = 2,
            seller = secondWorker,
            products = listOf(coffee(), coffee(), beer(), beer(), beer(), beer(), beer()),
            isPaid = false
        ),

        Receipt(
            id = 3,
            seller = secondWorker,
            products = listOf(beer(), beer(), bread()),
            isPaid = false
        )
    ),

    workers = listOf(firstWorker, secondWorker)
)

/* Transforming Data */

val receipts = store.receipts // fetch the receipts
val productsLists = receipts.map { it.products } // List<List<Product>>
println(productsLists)
//By using the map operator, you can transform all the receipts collection
//elements to their respective products. Map iterates over each element of type T and passes it
//into a provided lambda function. The lambda function returns an element of type R,
//which in this case, turns each receipt item into a product.
//What you get back is a List of List of Products, which is fine, but clunky to work with.

val allProducts = receipts.flatMap { it.products } // List<Product>
println(allProducts)

val allProductsEarnings = receipts.flatMap { it.products }
  .map { it.price }
  .sumByDouble { it }
println(allProductsEarnings)

// filtering by condition
val paidReceipts = receipts.filter { it.isPaid }
println(paidReceipts)

// grouping values by condition
val paidUnpaid = receipts.partition { it.isPaid }
val (paid, unpaid) = paidUnpaid
println(paid)
println(unpaid)

val groupedByWorker = receipts.groupBy { it.seller } // Map<Worker, List<Receipt>>
println(groupedByWorker)

}

Output:
[[Product(id=1, name=Gluten-free bread, 1kg, price=5.0), Product(id=1, name=Gluten-free bread, 1kg, price=5.0), Product(id=1, name=Gluten-free bread, 1kg, price=5.0), Product(id=3, name=Ground coffee 1kg, price=5.0), Product(id=2, name=Beer, light, 0.5l, price=7.5)], [Product(id=3, name=Ground coffee 1kg, price=5.0), Product(id=3, name=Ground coffee 1kg, price=5.0), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5)], [Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=1, name=Gluten-free bread, 1kg, price=5.0)]]
[Product(id=1, name=Gluten-free bread, 1kg, price=5.0), Product(id=1, name=Gluten-free bread, 1kg, price=5.0), Product(id=1, name=Gluten-free bread, 1kg, price=5.0), Product(id=3, name=Ground coffee 1kg, price=5.0), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=3, name=Ground coffee 1kg, price=5.0), Product(id=3, name=Ground coffee 1kg, price=5.0), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=2, name=Beer, light, 0.5l, price=7.5), Product(id=1, name=Gluten-free bread, 1kg, price=5.0)]
95.0
[operations.Receipt@31befd9f]
[operations.Receipt@31befd9f]
[operations.Receipt@548c4f57, operations.Receipt@1218025c]
{Worker(id=1, name=Filip)=[operations.Receipt@31befd9f], Worker(id=2, name=Chris)=[operations.Receipt@548c4f57, operations.Receipt@1218025c]}

Hey @kruger! :]

Printing out objects in Kotlin, by default, formats them as their type and memory address. Once you overload toString(), or add the data modifier to the class, you can print it in a reasonable way.

I notice that the Receipt doesn’t have a data modifier in the Tutorial, or your code, so adding that to Receipt will fix the problem! Thanks for noticing this, we will have to update the snippets! ^^

Thanks,
Filip B.