Итак, у вас есть DAG глубины 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 }
}
Корневым / верхним элементом будет любой элемент, родитель которого равен нулю. И тогда его категории - его непосредственные дети, а его подкатегории - его внуки. Я предоставил здесь свойство, которое будет заботиться о внуках, если вы действительно хотите этот метод доступа, и это означает, что если вы добавите что-то к ребенку, внуки родителей будут обновлены автоматически: 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