Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten array in Kotlin

I have a two dimensional array of Nodes that I want to flatten into a single array of all nodes using the flatten function of Kotlin arrays.

    val nodes = kotlin.Array(width, { width ->
    kotlin.Array(height, { height -> Node(width, height) })
})

I then try to call the flatten function on the 2D array

nodes.flatten()

but I get an error: Type mismatch: inferred type is Array<Array<Node>> but Array<Array<out ???>> was expected. Is there another way I should be doing this?

like image 455
Matt Mohandiss Avatar asked Jan 04 '17 16:01

Matt Mohandiss


People also ask

What is flatten in Kotlin?

flatten(): List<T> Returns a single list of all elements from all collections in the given collection.

What is the difference between FlatMap and map in Kotlin?

FlatMap is used to combine all the items of lists into one list. Map is used to transform a list based on certain conditions.

How do you use the FlatMap in Kotlin?

Returns a single list of all elements yielded from results of transform function being invoked on each element of original array. Returns a single list of all elements yielded from results of transform function being invoked on each element of original collection.

How do you use kotlin reduce?

Accumulates value starting with the first element and applying operation from left to right to current accumulator value and each element. Throws an exception if this array is empty. If the array can be empty in an expected way, please use reduceOrNull instead.


2 Answers

Use a more universal flatMap:

nodes.flatMap {it.asIterable()}
like image 117
voddan Avatar answered Oct 08 '22 01:10

voddan


Arrays in Kotlin are invariant so an Array<Array<Node>> is not an Array<Array<out T>> (which is the receiver type for flatten).

It looks like this will be fixed in Kotlin 1.1: Relax generic variance in Array.flatten · JetBrains/kotlin@49ea0f5.

Until Kotlin 1.1 is released you can maintain your your own version of flatten:

/**
 * Returns a single list of all elements from all arrays in the given array.
 */
fun <T> Array<out Array<out T>>.flatten(): List<T> {
    val result = ArrayList<T>(sumBy { it.size })
    for (element in this) {
        result.addAll(element)
    }
    return result
}
like image 39
mfulton26 Avatar answered Oct 08 '22 01:10

mfulton26