DhiWise Logo

Design Converter

  • Technologies
  • Resource
  • Pricing

Education

Kotlin GroupingBy vs GroupBy: What’s Right for Your Project in 2024?

Last updated on Sep 3, 2024

6 mins read

When working with collections in Kotlin, you often need to group elements based on certain criteria. Kotlin provides two powerful functions in its standard library for grouping: groupBy and groupingBy. Though they may seem similar, these functions serve different purposes and have unique use cases.

In this blog, we will explore the differences between groupBy and groupingBy in Kotlin, their syntax, use cases, and how to implement custom operations on grouped data. By the end of this guide, you'll understand how to use these functions effectively in your Kotlin code.

Understanding Grouping in Kotlin

Grouping is a common operation when dealing with collections. It involves categorizing elements based on a key, which is typically derived using a lambda function. The key could be the first character of a string, the result of a mathematical operation, or any other logic defined by a lambda argument. Both groupBy and groupingBy allow you to group collection elements by a key but differ in how they perform operations on the grouped data.

What is groupBy in Kotlin?

The groupBy function is an extension function provided by the Kotlin standard library that allows you to group all the elements of a collection into a Map<K, List<V>>. Here, K represents the key and List<V> contains the values corresponding to that key. This function is quite powerful and can be used to group elements based on any criteria.

Syntax of groupBy

1fun <T, K> Iterable<T>.groupBy( 2 keySelector: (T) -> K 3): Map<K, List<T>>

• keySelector is a lambda argument that defines how to determine the key for grouping collection elements.

Example of groupBy

Let's take a simple example where you group a list of strings by their first letter:

1val names = listOf("Alice", "Bob", "Charlie", "David", "Amanda") 2val groupedByFirstLetter = names.groupBy { it.first() } 3 4println(groupedByFirstLetter)

Output:

1{A=[Alice, Amanda], B=[Bob], C=[Charlie], D=[David]}

In this example, the groupBy function groups the elements of the names list by their first letter.

What is groupingBy in Kotlin?

The groupingBy method returns a Grouping object, which is a specialized interface in Kotlin that allows you to perform aggregate operations on the groups. Unlike groupBy, groupingBy does not immediately return a result map. Instead, it provides an intermediate step where you can perform custom operations on each group.

Syntax of groupingBy

1fun <T, K> Iterable<T>.groupingBy( 2 keySelector: (T) -> K 3): Grouping<T, K>

• keySelector is a lambda argument used to select the key for grouping elements.

Example of groupingBy

Consider the following example where we group names by their first letter and count the number of names in each group:

1val names = listOf("Alice", "Bob", "Charlie", "David", "Amanda") 2val grouping = names.groupingBy { it.first() }.eachCount() 3 4println(grouping)

Output:

1{A=2, B=1, C=1, D=1}

In this example, the groupingBy method creates a Grouping object, and the eachCount function is applied to count the number of elements in each group.

Key Differences Between groupBy and groupingBy

While both groupBy and groupingBy functions are used for grouping in Kotlin, there are key differences in their usage, performance, and flexibility:

1. Return Type and Operations

groupBy: Returns a Map<K, List<V>> immediately, where you can access the grouped elements directly. It is suitable when you only need to group elements and retrieve the result map.

groupingBy: Returns a Grouping object, which is more versatile and allows you to implement custom operations like counting, reducing, or aggregating on the groups. You need to call an additional function such as eachCount, fold, or aggregate to get the final result.

2. Performance Considerations

groupBy: Since it immediately creates a Map with grouped data, it might consume more memory for large collections. It is better suited for one-time operations.

groupingBy: Lazily evaluates the grouping and only computes the result when a terminal operation like eachCount or fold is called. This approach is more memory efficient when performing multiple operations on the same data.

3. Use Cases and Flexibility

groupBy: Use this when you need a simple grouping of elements and the resulting map will be used as-is. It is great for straightforward tasks like grouping by the first character or category.

groupingBy: Ideal when you need to perform multiple or complex operations on grouped data. It allows you to chain methods like fold and aggregate to perform complex data transformations.

4. Examples of Custom Operations with groupingBy

With groupingBy, you can use a value transformation function to perform more complex aggregations. Here is an example of using fold to create a custom grouping operation.

1data class Product(val name: String, val category: String, val price: Double) 2 3val products = listOf( 4 Product("Laptop", "Electronics", 1200.0), 5 Product("Phone", "Electronics", 800.0), 6 Product("T-shirt", "Clothing", 20.0), 7 Product("Jeans", "Clothing", 40.0) 8) 9 10val totalPricesByCategory = products.groupingBy { it.category } 11 .fold(0.0) { accumulator, element -> accumulator + element.price } 12 13println(totalPricesByCategory)

Output:

1{Electronics=2000.0, Clothing=60.0}

Here, the groupingBy method is used to create a grouping object, and the fold function is applied to calculate the total prices for each category.

When to Use groupBy vs groupingBy

Use groupBy When:

  1. You need a quick, in-memory grouping of elements.

  2. You are only interested in the grouped elements without additional operations.

  3. The result needs to be accessed multiple times and remains static.

Use groupingBy When:

  1. You want to perform operations like count, fold, or aggregate on grouped data.

  2. You need to optimize memory usage and delay computation until necessary.

  3. You are working with large datasets where only the grouping structure is important until the final result is calculated.

Conclusion

In this article on "Kotlin GroupingBy vs GroupBy," we explored the differences between the groupBy and groupingBy functions in Kotlin and their respective use cases. While both are used for grouping collection elements, groupBy is more straightforward, returning a Map<K, List<V>> directly, making it suitable for simpler tasks.

On the other hand, groupingBy provides a Grouping object, allowing more flexibility for complex operations like aggregation and transformation using functions such as fold and eachCount. The choice between groupBy and groupingBy depends on the specific requirements of your task, such as performance, memory usage, and the need for custom operations. Understanding these distinctions will help you use Kotlin’s powerful grouping capabilities more effectively in your projects.

Short on time? Speed things up with DhiWise!

Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!

You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.

Sign up to DhiWise for free

Read More