如何在不重复的情况下将项目插入项目列表

时间:2019-04-10 10:29:19

标签: android kotlin

我有一个dataClass,它包含一个唯一的code项,父代码和两个列表-categoriessubcategories

data class MyItem (
        var code: String,
        var name: String,*
        var data: String,
        var count: Int,
        var parent: String,
        var categories: MutableList<MyItem>,
        var subcategories: MutableList<MyItem>
)

我从服务器获得了3个不同的项目列表。我想要得到的结构是:

- listOfTopLevelItems
--- listOfMiddleLevelItems
----- listOfBottomLevelItems

其中每个topLevelItem包含一个middleLevelItems列表,每个中级项目包含一个下级项目列表。为此,我使用下面的代码

                for (topItem in topLevelItems) {
                    for (middleItem in middleLevelItems) {
                        if (topItem.code == middleItem.parent) {
                            val middleResultItem = middleItem

                            for (bottomItem in bottomLevelItems) {
                                if (middleItem.code == bottomItem.parent) {
                                    middleResultItem.subcategories.add(bottomItem)
                                }
                            }

                            topItem.categories.add(middleResultItem)
                        }
                    }

                    result.add(topItem)
                }

但是问题是,如果我在底层有很多项目,那么将会有很多迭代。还有另一种解决方法吗?

1 个答案:

答案 0 :(得分:0)

因此,您拥有的是深度3的DAG。除了解决迭代问题之外,我还将进行其他一些调整。

首先,我认为数据类的结构对于描述对象图有点多余。我认为您不需要类别和子类别字段。除去不相关的字段,这就是我的样子:

data class MyItem(
        var code: String,
        var parent: String? = null,
        var categories: MutableList<MyItem> = mutableListOf()
){
    val subcategories: List<MyItem>
        get() = categories.flatMap { it.categories }

}

根项/顶层项将是父项为null的任何项。然后,其类别是其直系子代,其子类别是其子代。我在这里提供了一个属性,如果您确实想要该访问者,它将照顾孙辈,这意味着,如果您向孩子添加一些东西,父母的孙辈将自动更新:D。

现在是创建对象图的版本1。这使事情与您了解哪些是根,孩子和大孩子的表象结构保持一致。但这不是必需的,正如您将在版本2中看到的那样。

fun main() {
    val topItems = listOf(MyItem("1"), MyItem("2"))
    val middleItems = listOf(MyItem("1_1", "1"), MyItem("1_2", "1"), MyItem("2_1", "2"))
    val bottomItems = listOf(MyItem("1_1_1", "1_1"), MyItem("1_2_1", "1_2"), MyItem("2_1_1", "2_1"))

    val topByID = topItems.map { it.code to it }.toMap()
    val middleByID = middleItems.map { it.code to it }.toMap()

    bottomItems.forEach { middleByID[it.parent]?.categories?.add(it) }
    middleItems.forEach { topByID[it.parent]?.categories?.add(it) }

    println(topItems)
    println(topItems[0].subcategories)
}

但是,实际上,构建对象图所需了解的只是父子关系,它们都可以放在一个大集合中。然后,您可以像这样重建对象图:

fun main() {
    val topItems = listOf(MyItem("1", "*"), MyItem("2", "*"))
    val middleItems = listOf(MyItem("1_1", "1"), MyItem("1_2", "1"), MyItem("2_1", "2"))
    val bottomItems = listOf(MyItem("1_1_1", "1_1"), MyItem("1_2_1", "1_2"), MyItem("2_1_1", "2_1"))

    val allItems = topItems + middleItems + bottomItems
    val allItemsByID = allItems.map { it.code to it }.toMap()

    allItems.forEach {
        allItemsByID[it.parent]?.categories?.add(it)
    }

    println(topItems)
    println(topItems[0].subcategories)
}

这是我最喜欢的方法:D