Imagine a list of lists, for example
List lists = [[[1]], [[2]], [[3]], [[4]], [[5]], [[6]], [[7]], [[8]], [[9]], [[10]]]
This is just an example - the inner lists may contain multiple elements. I want to flatten the list by one level without mutating variables. The result should be
[[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]]
Is there a good way in Groovy for that? It should be almost as fast as
lists.inject([]) { a, b -> a.addAll(b); a }
lists.flatten()flattens across all levels, resulting in[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].lists.sum()is concise and does the job, but sadly in O(n2) for this case. It should be done in O(n).- The Java Streams way
lists.stream().flatMap(List::stream).toList()seems to be O(n) in Groovy, but I was'nt so sure at first as it apparently comes with an extreme overhead compared to using it directly in Java. You can speed it up by a factor of 10 to 100 by just wrapping it in a method using@CompileStatic. Then it would be fast, but that is not really a convenient solution. There must be another way.
Ah, apparently that is what
lists.collectMany { it }is for...collectMany()is a bit likeflatMapin Scala or Java Streams. It does not mutate variables at top level and is reasonably fast: Not as fast asbut much faster than
I have played around with it and
collectMany()is more powerful than the standardflatMapand pretty cool to use, also for concatenating Maps.