Kotlin 声明嵌套数组

Kotlin declare nested array

如何在 Kotlin 中声明嵌套列表? 我正在寻找以下形式的内容:

var nestedList:List = [1,[2,[3,null,4]],[null],5]

以便我稍后可以将其展平(结果应为 nestedList = [1, 2, 3, 4, 5])。

如果你有嵌套数组结构(例如,val array: Array<Array<out Int?>> = arrayOf(arrayOf(1), arrayOf(2), arrayOf(3, null, 4))),你可以只使用flatten扩展方法:

println(array.flatten().filterNotNull())

所有常见的 collections 都无法保持可变层数,因此使用它们您只能制作像 Andrey Ilyunin 所写的东西 - val array: Array<Array<out Int?>>.

但我写了 class 结构来帮助您实现目标。它不是另一个 collection,您不能像现在这样使用它,但它可以制作您想要的任何层数。它是完全通用的,所以你不仅可以放在那里Int

首先,我们从NestedArrayItem class开始,代表单项或多嵌套数组:

class NestedArrayItem<T> {
    private val array: ArrayList<NestedArrayItem<T>>?
    private val singleItem: T?
    constructor(array: ArrayList<NestedArrayItem<T>>) {
        this.array = array
        singleItem = null
    }
    constructor(singleItem: T?) {
        this.singleItem = singleItem
        array = null
    }
    fun asSequence(): Sequence<T?> =
        array?.asSequence()?.flatMap { it.asSequence() } ?:
            sequenceOf(singleItem)
    override fun toString() =
        array?.joinToString(prefix = "[", postfix = "]") ?:
            singleItem?.toString() ?: "null"
}

然后 class NestedArray 这就像所有层的顶级容器:

class NestedArray<T> {
    private val array: ArrayList<NestedArrayItem<T>> = arrayListOf()

    fun add(value: T?) {
        array.add(NestedArrayItem(value))
    }

    fun addNested(nestedArray: NestedArray<T>) {
        array.add(NestedArrayItem(nestedArray.array))
    }

    fun flatten(): ArrayList<T?> = array.asSequence()
        .flatMap { it.asSequence() }
        .toCollection(arrayListOf())

    override fun toString() = array.joinToString(prefix = "[", postfix = "]")
}

为了更容易编写值,我还为此编写了生成器 class:

class NestedArrayBuilder<T> private constructor(private val result: NestedArray<T>){
    constructor(fillNestedBuilder: NestedArrayBuilder<T>.() -> Unit) : this(NestedArray()) {
        NestedArrayBuilder(result).apply(fillNestedBuilder)
    }
    fun add(value: T?): NestedArrayBuilder<T> {
        result.add(value)
        return this
    }
    fun addArray(fillNestedBuilder: NestedArrayBuilder<T>.() -> Unit): NestedArrayBuilder<T> {
        val nestedResult = NestedArray<T>()
        val nestedArray = NestedArrayBuilder(nestedResult).apply(fillNestedBuilder)
            .build()
        result.addNested(nestedArray)
        return this
    }

    fun build() = result
}

就是这样!你可以使用它。我在这里举例说明如何使用它:

val array = NestedArrayBuilder<Int> {
    add(1)
    addArray {
        add(2)
        addArray {
            add(3)
            add(null)
            add(4)
        }
    }
    addArray {
        add(null)
    }
    add(5)
}.build()
assertEquals("[1, [2, [3, null, 4]], [null], 5]", array.toString())
assertEquals(arrayListOf(1, 2, 3, null, 4, null, 5), array.flatten())