Estoy tratando de refactorizar la siguiente función para hacerla más idiomática de Kotlin utilizando funciones modernas de lenguaje funcional:
fun foobar(): List<Account> { var pageOffset = 0 val accounts: MutableList<Account> = ArrayList() var chunk: List<Account> = accountsService.getAccounts(pageOffset, MAX_POLL_SIZE) while (chunk.isNotEmpty()) { accounts.addAll(chunk) pageOffset += MAX_POLL_SIZE chunk = accountsService.getAccounts(pageOffset, MAX_POLL_SIZE) } return accounts }Mi primer intento fue reemplazar la lista mutable con buildList, pero todavía no tiene un estilo bastante funcional:
fun foobar2(): List<Account> { var pageOffset = 0 return buildList { var chunk: List<Account> = accountsService.getAccounts(pageOffset, MAX_POLL_SIZE) while (chunk.isNotEmpty()) { addAll(chunk) pageOffset += MAX_POLL_SIZE chunk = accountsService.getAccounts(pageOffset, MAX_POLL_SIZE) } } } Idealmente, me gustaría reemplazar todo el ciclo while con algo como accountsService.getAccounts(...).map { ... } pero no puedo descifrar cómo refactorizar un ciclo while que tiene este tipo de "primer fragmento". seguido de una serie de fragmentos adicionales. Se puede hacer?
Puedes hacer algo como esto:
fun foobar(): List<Account> = generateSequence(0) { it + MAX_POLL_SIZE }.map { offset -> accountsService.getAccounts(offset, MAX_POLL_SIZE) }.takeWhile { it.isNotEmpty() }.flatten().toList() generarSequence generateSequence una secuencia perezosa infinita que comienza con 0 , MAX_POLL_SIZE , MAX_POLL_SIZE * 2 , MAX_POLL_SIZE * 3 , y así sucesivamente. Esta es la secuencia de desplazamientos de página para los que obtiene cuentas. Transformamos cada desplazamiento de página a la lista de cuentas a las que corresponde, usando map . Después de eso, especificamos el final de la secuencia infinita usando takeWhile .
Ahora tenemos una Sequence<List<Account>> , por lo que usamos flatten convierte eso en una Sequence<Account> , que luego se puede convertir trivialmente en List<Account> ,