科特林。在嵌套列表中按参数查找元素

Kotlin. Find element by param in nested lists

我有一些data clases

data class Data(val docNumber: Int?,
            val docType: Int?, 
            val fiscprops: List<FiscProp>, 
            val name: String? 
 ) {

fun getFiscProp(tag: Int) = fiscprops.firstOrNull { it.tag == tag }

}

data class FiscProp(val caption: String?,
                val printable: String?,
                val tag: Int?,
                val value: Any?,
                val fiscprops: List<FiscProp>?) 

我需要在嵌套的 lists 中通过 tag 找到 FiscProp。如果我使用 getFiscProp,我只能在第一层找到 FiscProp

如何在所有级别上找到元素?不知道会到几级

您可以为此使用基本的递归搜索:

fun List<FiscProp>.getFiscProp(tag: Int): FiscProp? {
    for (fiscProp in this) {
        if (fiscProp.tag == tag)
            return fiscProp
        val found = fiscProp.fiscprops?.getFiscProp(tag)
        if (found != null)
            return found
    }
    return null
}

我觉得这个功能版应该也可以,但是我没测试过:

fun List<FiscProp>.getFiscProp(tag: Int): FiscProp? = firstNotNullOfOrNull {
    if (it.tag == tag) it else it.fiscprops?.getFiscProp(tag)
}
val FiscProp.allProps: Sequence<FiscProp>
    get() = sequence {
        yield(this@allProps)
        fiscprops?.forEach {
            yieldAll(it.allProps)
        }
    }

class Data(...) {

    fun getFiscProp(tag: Int) = fiscprops.asSequence()
        .flatMap { it.allProps}
        .firstOrNull { it.tag == tag }
}

这是一个尾递归版本。

data class Data(...) {
    fun findByTag(tag: Int) = findByTag(fiscprops, tag)

    private tailrec fun findByTag(fiscprops: List<FiscProp>, tag: Int): FiscProp? =
        if (fiscprops.isEmpty()) null
        else {
            val fiscprop = fiscprops.first()
            if (fiscprop.tag == tag) fiscprop
            else findByTag(fiscprops.drop(1) + fiscprop.fiscprops.orEmpty(), tag)
        }
}