Fold vs Reduce en Kotlin: ¿cuándo usar cada uno? Análisis completo

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Fold o Reduce en Kotlin: la eterna pregunta de los principiantes

\n\n

Si llevas al menos una semana programando en Kotlin, seguro que ya te has topado con las funciones fold y reduce. A primera vista, hacen lo mismo: recorren una colección y acumulan un resultado. Pero el diablo, como siempre, está en los detalles. Una elección incorrecta puede provocar errores, excepciones o simplemente código poco elegante.

\n\n

En este artículo analizaremos la diferencia entre fold y reduce en Kotlin, veremos ejemplos prácticos de proyectos reales y recordaremos para siempre cuándo usar cada función. ¡Allá vamos!

\n\n

¿Qué son fold y reduce? Conceptos básicos

\n\n

Ambas funciones son operaciones terminales para colecciones. Toman todos los elementos y los reducen a un solo valor. Imagina que tienes una pila de panqueques y quieres obtener una gran hamburguesa. fold y reduce son dos técnicas diferentes para apilarlos.

\n\n

Reduce: el enfoque minimalista

\n\n

La función reduce usa el primer elemento de la colección como valor inicial del acumulador. Esto significa que simplemente no puede trabajar con una colección vacía: lanzará una UnsupportedOperationException.

\n\n
val numbers = listOf(1, 2, 3, 4, 5)\nval sum = numbers.reduce { acc, i -> acc + i }\nprintln(sum) // 15
\n\n

Aquí acc inicialmente es 1 (el primer elemento), luego se le suma 2, luego 3, y así sucesivamente. Simple y elegante, pero hay un detalle.

\n\n

Fold: control sobre el inicio

\n\n

fold, a diferencia de reduce, requiere que especifiques explícitamente un valor inicial. Esto te da control total y, lo que es más importante, permite trabajar con colecciones vacías.

\n\n
val numbers = listOf(1, 2, 3, 4, 5)\nval sum = numbers.fold(0) { acc, i -> acc + i }\nprintln(sum) // 15\n\nval emptyList = listOf<Int>()\nval emptySum = emptyList.fold(0) { acc, i -> acc + i }\nprintln(emptySum) // 0, ¡sin errores!
\n\n

¿Ves la diferencia? fold devuelve el valor inicial si la colección está vacía. reduce en esa situación fallaría.

\n\n

Diferencias clave entre fold y reduce en Kotlin

\n\n

Organicemos los conocimientos. Aquí tienes una tabla que te ayudará a orientarte rápidamente:

\n\n
    \n
  • Valor inicial: En fold lo defines tú. En reduce es el primer elemento de la colección.
  • \n
  • Tipo de resultado: En fold el tipo de resultado puede diferir del tipo de los elementos (por ejemplo, sumas Int y obtienes String). En reduce el tipo de resultado siempre coincide con el tipo de los elementos.
  • \n
  • Colección vacía: fold la maneja correctamente (devuelve el valor inicial). reduce lanza una excepción.
  • \n
  • Rendimiento: Ambas funciones tienen complejidad O(n). La diferencia de rendimiento es imperceptible.
  • \n
\n\n

Ahora veamos esto en código.

\n\n

Ejemplo 1: Diferentes tipos de acumulador y elementos

\n\n

Supongamos que tenemos una lista de números y queremos obtener una cadena con su suma en formato legible. fold lo hace perfectamente porque el tipo del acumulador (String) es diferente al tipo de los elementos (Int).

\n\n
val numbers = listOf(1, 2, 3)\nval result = numbers.fold("Suma: ") { acc, i -> "$acc$i " }\nprintln(result) // "Suma: 1 2 3 "
\n\n

Intenta hacer lo mismo con reduce: el compilador dará un error porque reduce requiere que el tipo del acumulador coincida con el tipo de los elementos.

\n\n

Ejemplo 2: Cálculo de suma con valor inicial

\n\n

Una tarea común: calcular el total de pedidos, pero ya tenemos un saldo inicial en la cuenta.

\n\n
val orders = listOf(100, 250, 75)\nval initialBalance = 500\nval totalBalance = orders.fold(initialBa                

Blogs

Book Recommendations