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

332
Vistas
Split a lists into multiple sub lists with predicate - looking for a nice way to write this code

Lets say I have a list of integers: [2, 4, 4, 6, 1, 8, 3, 5, 2, 2, 2], and I want to split this lists into sub lists so each sub list contain values that match the predicate, or if it doesn't then only the value that didn't match, and it should be in the order of the original list.

So for example, if the predicate is "is even" I expect to get the following result: [[2, 4, 4, 6],[1],[8],[3, 5],[2, 2, 2]]

I have a code that works, but it's pretty ugly in my opinion and I feel like there should be a much nicer way to write it:

private fun <T : Any> toSubLists(values: List<T>, predicate: (T) -> Boolean): List<List<T>> {
  val subLists = mutableListOf<List<T>>()
  var currentList = mutableListOf<T>()
  values.forEach {
    if (!predicate(it)) {
      if (currentList.isNotEmpty()) {
        subLists.add(currentList)
        currentList = mutableListOf()
      }
      subLists.add(listOf(it))
    } else {
      currentList.add(it)
    }
  }
  if (currentList.isNotEmpty()) {
    subLists.add(currentList)
  }
  return subLists
}
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Not sure if it's better because it might be harder to understand, but this is a way to do it

private fun <T : Any> toSubLists(values: List<T>, predicate: (T) -> Boolean): List<List<T>> = 
    values.withIndex().groupBy({
        var index = it.index
        while (index != 0 && predicate(values[index]) && predicate(values[index - 1])) index--
        index
    }){
        it.value
    }.values.toList()

see it working here

over 4 years ago · Santiago Trujillo Denunciar

0

There is a feature request for a generic version of this that accepts other key selectors than predicates.

In the meantime, for your use case I think we can simplify a bit:

fun <T> List<T>.groupRunsBy(predicate: (T) -> Boolean): List<List<T>> {
    val result = mutableListOf<MutableList<T>>()
    var currentlyMatching: Boolean? = null
    forEach {
        val itemMatches = predicate(it)
        if (itemMatches == currentlyMatching) {
            result.last().add(it)
        } else {
            currentlyMatching = itemMatches
            result.add(mutableListOf(it))
        }
    }
    return result
}

fun main() {
    val list = listOf(2, 4, 4, 6, 1, 8, 3, 5, 2, 2, 2)
    
    println(list.groupRunsBy { it % 2 == 0 }) // [[2, 4, 4, 6], [1], [8], [3, 5], [2, 2, 2]]
}

Tested here: https://pl.kotl.in/OHVr7S6lX

This version can easily be changed to support any selector that returns non-null keys.

over 4 years ago · Santiago Trujillo Denunciar

0

fun <T : Any> toSubLists(values: List<T>, predicate: (T) -> Boolean): List<List<T>> {
  val items = values.map { predicate(it) to listOf(it) }.toMutableList()
  for (i in items.indices.last downTo 1) {
    if (items[i - 1].first && items[i].first) {
      items[i - 1] = items[i - 1].first to items[i - 1].second + items[i].second
      items.removeAt(i)
    }
  }
  return items.map { it.second }
}

val list1 = listOf(2, 4, 4, 6, 1, 8, 3, 5, 2, 2, 2)
val isOdd: (Int) -> Boolean = { it % 2 != 0 }
val isEven: (Int) -> Boolean = { it % 2 == 0 }

println(toSubLists(list1, isOdd))   // [[2], [4], [4], [6], [1], [8], [3, 5], [2], [2], [2]]
println(toSubLists(list1, isEven))  // [[2, 4, 4, 6], [1], [8], [3], [5], [2, 2, 2]]
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