简体   繁体   中英

Kotlin FlatMap && Recursion

I have a data structure which is a tree. Each Item has children, and they may have children etc:

class NavigationItem(
    val title: String,
    val parent: NavigationItem?
) {
    val children: MutableList<NavigationItem> = mutableListOf()
    val isLeaf: Boolean
        get() = children.count() == 0

    val allChildren: List<NavigationItem>
        get() = children.flatMap {
            it.allChildren
        }
}

I assumed the allChildren synthetic property would traverse the graph, mapping into it's children the allChildren property and go all the way through.

This is not what is happening:

@Test
fun testAllChildrenProperty() {
    val root = NavigationItem("Root", null).apply {
        children.add(NavigationItem("Level 1", this))
        children.add(NavigationItem("Level 1", this))
    }
    assertEquals(2 ,root.allChildren.count())
}

This unit test fails -- we are just getting an empty list for allChildren. Can anyone explain A) what flatMap in kotlin does and B) What should I be using instead?

Your understanding of the flatMap function seems correct, and your use of recursion looks fine. The problem is that although you recurse through all the children, you never actually add any of them to the returned list!

How about this?

val allChildren: List<NavigationItem>
    get() = children + children.flatMap { it.allChildren }

Note the inclusion of the children + , which ensures each child is itself added to the returned list as well as all of its children.

You would need to add some more complex logic if there's a possibility of cycles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM