Как сканировать рекурсивные структуры с использованием Kotlin сопрограмм? - PullRequest
1 голос
/ 04 апреля 2020

Учитывая древовидную структуру и операцию для извлечения дочерних элементов узла, например:

typealias NodeReference = URL 

data class Node(
     val data:Data,
     val childrenList:List<NodeReference>)

suspend fun resolve(nodeRef:NodeReference) : Node    

Знаете ли вы план реализации функции сканера, имеющей подпись

fun nodeList(rootNode:NodeReference) : List<Node> = 
    runBlocking(...) {
      ...
    }

возврат всех узлов дерева с использованием Kotlin сопрограмм?

1 Ответ

2 голосов
/ 04 апреля 2020

Чтобы эффективно решить эту проблему, вы должны:

  1. Разрешить rootRef: NodeReference, чтобы получить rootNode: Node
  2. Рекурсивно асинхронно вызывать nodeList метод для всех children из rootNode
  3. Ожидайте результатов
  4. Объедините результаты и добавьте к ним rootNode

Вот как вы можете это сделать:

suspend fun nodesList(rootRef: NodeReference): List<Node> = coroutineScope {
    val rootNode = resolve(rootRef) // 1
    rootNode.childrenList
        .map { async { nodesList(it) } } // 2
        .awaitAll() // 3
        .flatten() + rootNode // 4
}

Если вы хотите использовать текущий поток для выполнения nodesList, вы можете сделать это следующим образом:

fun nodesListBlocking(rootRef: NodeReference): List<Node> = runBlocking { nodesList(rootRef) }
...