What does the standard-library function `groupBy` do, and what is the exact type of the value it returns?
answer
- Returns Map<K, List<T>>
- Backed by LinkedHashMap — order preserved
- Two-arg overload adds valueTransform
- Eager, even on Sequence
- Counts? use groupingBy().eachCount()
basics
~10 sgroupBy sorts items into buckets using a key you choose. It returns a map where each key points to a list of all the items that produced that key.
solid answer
~30 s`groupBy(keySelector)` walks the collection and builds a `Map<K, List<T>>`: for every element it computes a key with the lambda, and appends the element to the list stored under that key. Insertion order of both keys and per-key elements is preserved (it is backed by a `LinkedHashMap`). The two-argument overload `groupBy(keySelector, valueTransform)` returns `Map<K, List<V>>`, transforming each element before storing it. It is eager and runs immediately on `Iterable`/`Array`/`Sequence`. Example: `words.groupBy { it.first() }` yields `Map<Char, List<String>>`. For just counting use `groupingBy().eachCount()` instead, which avoids materializing the lists.
code
kotlin · 3 linesval nums = listOf(1, 2, 3, 4, 5, 6)
val parity = nums.groupBy { if (it % 2 == 0) "even" else "odd" }
// {odd=[1, 3, 5], even=[2, 4, 6]}go deeper
Knows groupBy buckets elements into a Map<K, List<T>> by a derived key.
Mentions the valueTransform overload and that order is preserved via LinkedHashMap.
Notes it is eager even on sequences and contrasts with groupingBy().eachCount() for count-only needs.
Reasons about memory cost of materializing per-key lists vs streaming counts, and picks the right tool for large datasets.
## What `groupBy` is `groupBy` is an extension on `Iterable<T>`, `Array<T>`, and `Sequence<T>` that **restructures** a flat collection into a `Map` keyed by a value you derive from each element. ## Signatures - `groupBy(keySelector: (T) -> K): Map<K, List<T>>` - `groupBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, List<V>>` The single-argument form keeps the original elements; the two-argument form stores a transformed value instead. ## Semantics - For each element, the `keySelector` lambda computes a key. - The element (or its transform) is **appended** to the list under that key. - The backing map is a `LinkedHashMap`, so **key insertion order** and the **order of elements within each list** are preserved. - It is **eager**: even on a `Sequence`, calling `groupBy` consumes it and returns a fully built map. ## Example ```kotlin val words = listOf("apple", "avocado", "banana", "cherry") val byFirst: Map<Char, List<String>> = words.groupBy { it.first() } // {a=[apple, avocado], b=[banana], c=[cherry]} val lengths: Map<Char, List<Int>> = words.groupBy({ it.first() }, { it.length }) // {a=[5, 7], b=[6], c=[6]} ``` ## When to reach for something else - If you only need **counts**, prefer `groupingBy { ... }.eachCount()` — it returns `Map<K, Int>` without building intermediate lists. - If each key maps to exactly **one** value (not a list), use `associateBy` / `associate` instead.
- If two elements produce the same key, what happens?Both are kept — they are appended to the same list under that key. No element is lost, unlike associateBy which keeps only the last.
- Is the returned map mutable?The declared return type is the read-only Map, though the implementation is a LinkedHashMap; you should treat it as read-only.
Like sorting incoming mail into labeled pigeonholes — each slot ends up holding a stack of letters.
saying these in an interview costs you the question
- Saying groupBy returns Map<K, T> (single value) instead of Map<K, List<T>>
- Claiming groupBy is lazy on a Sequence
- Confusing groupBy with associateBy (which drops duplicates)
- Thinking order is randomized like a HashMap