Digamos que hay una función que devuelve un único valor de retorno anulable. Por ejemplo:
fun getItem(): String? Me gustaría crear una nueva lista de elementos llamando a esta función hasta que devuelva null .
Mi idea sería escribir un iterador que repita el valor de retorno hasta que sea null . Sin embargo, ¿existe una forma más elegante o idiomática de abordar este tema?
No estoy seguro de qué sería tbh idiomático, pero puede usar un while(true) para lograrlo.
val list = mutableListOf<String>() while (true) getItem()?.let { list += it } ?: breakEso básicamente se traduce en:
while true (infinite loop). if getItem() is not null, add it to the list. if getItem() is null, then break the loop.Como dice @Slaw en los comentarios, puede usar generateSequence y pasarle una referencia a su función (o una lambda que la llame si lo desea) para crear una Sequence que genere valores. Terminar cuando su función devuelve null es un comportamiento incorporado:
Devuelve una secuencia que invoca la función para calcular el siguiente valor en cada iteración hasta que la función devuelve un valor nulo.
Entonces, literalmente, puede simplemente hacer generateSequence(::getItem) para obtener su "iterador" y llamar a toList o cualquier función de secuencia que desee. Sin embargo, no es un Iterator real: puede obtener uno de esos haciendo toList() y luego llamando a iterator() en eso.
Hay muchas formas de obtener esta funcionalidad, pero creo que generateSequence es la más simple. Si necesita más control, puede encadenar una llamada takeWhile() para hacer una secuencia que termine en una condición/valor específico, o puede usar la función de creación de sequence para yield los elementos que necesita (por ejemplo, si desea tener valores nulos en allí). Y también hay enfoques que no son de secuencia como el truco de "agregar a una lista" de @Alex.T (aunque, no lo he comprobado, me imagino que eso es lo que generateSequence -> toList está haciendo debajo del capó)