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())
如何在 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())