What does flatten do, and how does it relate to flatMap? Show both with windowing/chunked output.
answer
- flatten = concat inner lists, one level
- flatMap = map + flatten in one pass
- chunked(n).flatten() round-trips
- windowed overlap -> flatten repeats elements
- Not recursive; not filterNotNull
basics
~20 sflatten takes a list of lists and concatenates them into one flat list, one level deep. flatMap maps each element to a collection and then flattens in a single step — so flatMap(f) equals map(f).flatten().
solid answer
~30 sflatten() is defined on Iterable<Iterable<T>> and returns a single List<T> by concatenating the inner collections in order, removing exactly one nesting level (not deep/recursive). It pairs naturally with chunked/windowed, which produce List<List<T>>: chunking then flatten() round-trips back to the original order. flatMap { ... } is map then flatten fused: list.flatMap(transform) == list.map(transform).flatten(), but flatMap is one pass and the idiomatic choice. There is also flatMapIndexed. Both are available lazily on Sequence. flatten only collapses one level, so a List<List<List<T>>> needs flatten().flatten(). For nullable inner-element cleanup use filterNotNull rather than flatten.
code
kotlin · 4 linesval nested = listOf(listOf(1, 2), listOf(3, 4))
println(nested.flatten()) // [1, 2, 3, 4]
println(nested.flatMap { it }) // [1, 2, 3, 4]
println(listOf("ab", "cd").flatMap { it.toList() }) // [a, b, c, d]go deeper
Knows flatten merges nested lists into one.
States the flatMap == map().flatten() identity and the one-level-only rule.
Connects flatten to chunked round-tripping and overlapping-windowed duplication; prefers flatMap for the fused single pass.
Reasons about lazy Sequence pipelines, allocation cost of intermediate nested lists, and API contracts (Iterable<Iterable> typing).
## flatten `flatten()` is an extension on `Iterable<Iterable<T>>` (and `Array<Array<T>>`). It **concatenates the inner collections in order** into one `List<T>`, removing **exactly one** level of nesting. ```kotlin listOf(listOf(1, 2), listOf(3), listOf(4, 5)).flatten() // [1, 2, 3, 4, 5] ``` It is **not recursive**: a triple-nested list needs `flatten().flatten()`. ## Round-tripping with chunked / windowed `chunked` and `windowed` produce `List<List<T>>`, so `flatten()` is the natural inverse for the non-overlapping case: ```kotlin val xs = listOf(1, 2, 3, 4, 5) xs.chunked(2).flatten() // [1, 2, 3, 4, 5] == xs ``` With **overlapping** `windowed`, flatten will repeat shared elements (because windows overlap), so it does **not** reconstruct the original — useful to remember. ```kotlin listOf(1, 2, 3).windowed(2).flatten() // [1, 2, 2, 3] (2 appears twice) ``` ## Relationship to flatMap `flatMap(transform)` is **map followed by flatten, fused into one pass**: ```kotlin val words = listOf("ab", "cd") words.flatMap { it.toList() } // [a, b, c, d] words.map { it.toList() }.flatten() // [a, b, c, d] (same result) ``` Use `flatMap` when you map-then-flatten in one step; use `flatten` when you already have nested collections. Related: `flatMapIndexed { index, e -> ... }`. ## Sequences Both `flatten()` and `flatMap` exist on `Sequence` and are **lazy**, so large or chained pipelines avoid materializing intermediate lists. ## Common confusion - `flatten` does **not** remove nulls — use `filterNotNull()` for `List<T?>` to `List<T>`. - `flatten` collapses **one** level only.
- Does chunked(n).flatten() always equal the original list?Yes for chunked, because chunks are non-overlapping and cover every element once. windowed (when overlapping) would duplicate shared elements.
- How do you flatten a List<List<List<Int>>> fully?Call flatten() twice: list.flatten().flatten(). flatten removes only one nesting level per call.
flatten empties several boxes into one drawer; flatMap unpacks each item into pieces and drops them straight into the drawer in one move.
saying these in an interview costs you the question
- Thinking flatten recurses through all nesting levels
- Saying flatten removes nulls (that is filterNotNull)
- Claiming flatMap and map().flatten() give different results
- Assuming windowed(...).flatten() reconstructs the original list
- Not knowing flatten works on Iterable<Iterable<T>> specifically