Plegado y reducción
foldLeft y reduce
Plegado y reducción es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
Combinar elementos en uno solo
A veces necesita combinar todos los elementos de una colección en un único valor, como una suma o una concatenación. Scala proporciona fold, foldLeft, foldRight y reduce para hacerlo.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
println(nums.sum)
println(nums.product)
}
}reduce: combinar sin valor inicial
reduce combina los elementos por pares mediante una función binaria. Necesita al menos un elemento; de lo contrario, lanza una excepción.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.reduce((a, b) => a + b)
println(total)
val max = nums.reduce((a, b) => if (a > b) a else b)
println(max)
}
}foldLeft: combinar con un valor inicial
foldLeft recibe un valor inicial, o semilla, y una función. Es seguro con colecciones vacías (devuelve la semilla) y permite que el tipo del resultado sea diferente del tipo de los elementos.
Sintaxis: xs.foldLeft(seed)((acc, x) => ...).
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val sum = nums.foldLeft(0)((acc, x) => acc + x)
println(sum)
val empty = List.empty[Int].foldLeft(0)(_ + _)
println(empty)
}
}El patrón del acumulador
En un fold, el primer argumento es el acumulador que contiene el resultado obtenido hasta el momento, y el segundo es el elemento actual. Cada paso actualiza el acumulador.
object Main {
def main(args: Array[String]): Unit = {
val words = List("Scala", "is", "great")
val sentence = words.foldLeft("")((acc, w) => acc + w + " ")
println(sentence.trim)
}
}El tipo del resultado puede ser diferente
Una característica potente de foldLeft es que el tipo del acumulador puede ser diferente del de los elementos. Aquí transformamos una lista de números en un String mediante un fold.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3)
val joined = nums.foldLeft("nums:")((acc, n) => acc + " " + n)
println(joined)
}
}foldRight: desde la derecha
foldRight procesa los elementos de derecha a izquierda. El acumulador es el segundo argumento: (x, acc) => .... La dirección es importante para las operaciones no conmutativas.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val left = nums.foldLeft("")((acc, x) => acc + x)
val right = nums.foldRight("")((x, acc) => acc + x)
println("foldLeft: " + left)
println("foldRight: " + right)
}
}De izquierda a derecha frente a derecha a izquierda y rendimiento
foldLeft es recursivo de cola y no desborda la pila con listas grandes. foldRight puede desbordar la pila en un List con entradas muy grandes. Prefiera foldLeft, salvo que el orden exija lo contrario.
object Main {
def main(args: Array[String]): Unit = {
val big = (1 to 100000).toList
val total = big.foldLeft(0L)((acc, x) => acc + x)
println(total)
}
}Construir una colección con fold
Los folds son suficientemente generales como para construir colecciones. Aquí invertimos una lista anteponiendo cada elemento a una lista acumuladora.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val reversed = nums.foldLeft(List.empty[Int])((acc, x) => x :: acc)
println(reversed)
}
}reduceOption para mayor seguridad
Como reduce falla con colecciones vacías, reduceOption devuelve un Option: Some(result) cuando no está vacía y None cuando está vacía.
object Main {
def main(args: Array[String]): Unit = {
println(List(3, 1, 4).reduceOption(_ + _))
println(List.empty[Int].reduceOption(_ + _))
}
}fold: una variante simétrica
fold es como foldLeft, pero el acumulador debe ser del mismo tipo que los elementos. Se suele utilizar con colecciones paralelas.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.fold(0)(_ + _)
println(total)
}
}Contar con foldLeft
Los folds pueden calcular resultados más elaborados, como contar cuántos elementos cumplen una condición, todo en un solo recorrido.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(4, 7, 2, 9, 6, 1)
val evenCount = nums.foldLeft(0)((acc, x) => if (x % 2 == 0) acc + 1 else acc)
println(s"even numbers: $evenCount")
}
}Comprobación rápida
¿Cuál es la diferencia fundamental entre reduce y foldLeft?
Resumen
Ha aprendido a plegar y reducir:
reduce— combina por pares, no usa valor inicial y falla si está vacíoreduceOption— variante segura que devuelveOptionfoldLeft— valor inicial + acumulador, segura para la pila y con tipo de resultado flexiblefoldRight— de derecha a izquierda; tenga cuidado con la pila en listas grandes- Los pliegues incluso pueden construir colecciones nuevas
Aprende Scala con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 39
- Lecciones
- 143
Preguntas frecuentes
¿La lección «Plegado y reducción» es gratis?
Sí — el texto completo de «Plegado y reducción» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
¿Qué aprenderé en «Plegado y reducción»?
foldLeft y reduce Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?
No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Plegado y reducción»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?
Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- List, Vector, Set, Map
- Transformaciones
- Plegado y reducción
- Agrupación y ordenamiento