Как сканировать рекурсивные структуры с помощью сопрограмм Kotlin?

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

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 ответ

Решение

Для эффективного решения этой проблемы вам следует:

  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) }
Другие вопросы по тегам