Kotlin声明嵌套数组

时间:2018-10-23 08:26:34

标签: list arraylist kotlin nested declare

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

所有常见集合都无法保持可变层数,因此,使用它们您只能像Andrey Ilyunin所写的那样-val array: Array<Array<out Int?>>

但是我写了类结构来帮助您实现目标。它不是另一个集合,您不能像现在那样使用它,但是它可以使您想要的任何层数达到目的。它是完全通用的,因此您不仅可以放置Int

首先,我们从NestedArrayItem类开始,该类代表单个项目或另一个嵌套数组:

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"
}

然后创建类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 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())