Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

202
Vistas
Find-first-and-transform for Sequence in Kotlin

I often stumble upon this problem but don't see a common implementation: how do I idiomatically (functionally) find an element, stop search after the match, and also return a different type (i.e. map whatever matched to another type)?

I've been able to do a workaround with

fun <F,T> Sequence<F>.mapFirst(block: (F) -> T?): T? =
    fold(AtomicReference<T>()) { ref, from ->
        if (ref.get() != null) return@fold ref
        ref.set(block(from))
        ref
    }.get()

fun main() {
    Files.list(someDir).asSequence().map { it.toFile() }.mapFirst { file ->
        file.useLines { lines ->
            lines.mapFirst { line ->
                if (line == "123") line.toInt() else null
            }
        }
    }?.let { num ->
        println("num is $num") // will print 123 as an Int
    } ?: println("not a single file had a line eq to '123'")
}

But that doesn't stop on the match (when block() returns non-null) and goes to consume all files and all their lines.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

A simple for loop is enough to implement mapFirst:

fun <F,T> Sequence<F>.mapFirst(block: (F) -> T?): T? {
    for (e in this) { 
        block(e)?.let { return it }
    }
    return null
}

If you need a solution without introducing your own extensions (though there's nothing wrong with it), you can use mapNotNull + firstOrNull combination:

files.asSequence()
    .mapNotNull { /* read the first line and return not null if it's ok */ }
    .firstOrNull()
over 4 years ago · Santiago Trujillo Denunciar

0

I would not map the values you discard then, instead do it like this:

sequenceOf(1, 2, 3)
    .firstOrNull() { it == 2 }
    ?.let { it * 2 } ?: 6

First you find the value that matches your condition, then you transform it too whatever you want. In case you don't find a matching element, you assign a default value (in this case 6).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda