Как вставить элементы в список элементов без большого количества итераций

#android #kotlin

#Android #kotlin

Вопрос:

У меня есть класс данных, который содержит уникальный code элемент, код родительского элемента и два списка — categories и subcategories .

 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
  

где каждый элемент верхнего уровня содержит список элементов среднего уровня, а каждый элемент среднего уровня содержит список элементов нижнего уровня. Для этого я использовал приведенный ниже код

                 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. Используйте Gson или любую библиотеку синтаксического анализа. он проанализирует ваш json в модель без каких-либо итераций.

2. @HemantParmar какое отношение к этому имеет Gson? В вопросе даже не упоминается JSON.

Ответ №1:

Итак, у вас есть база данных глубиной 3. Я собираюсь внести некоторые другие коррективы, помимо простого решения вашей итерационной проблемы.

Во-первых, я думаю, что структура ваших классов данных немного избыточна для описания графика объектов. На мой взгляд, вам не нужны поля категории и подкатегории. Удаление нерелевантных полей, вот как будет выглядеть мое:

 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