0Pricing
Scala for Backend Engineering & Functional Programming · Lección

foldLeft y foldRight

Reduzca colecciones a un valor

foldLeft y foldRight 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.

Plegar una colección

El plegado reduce una colección a un único valor combinando repetidamente sus elementos con un acumulador.

El patrón del acumulador que ha aprendido es exactamente lo que abstrae fold. En lugar de escribir la función auxiliar recursiva, proporciona un valor inicial y una función de combinación.

Conceptos básicos de foldLeft

foldLeft recibe un acumulador inicial y una función (acc, element), y recorre la colección de izquierda a derecha.

En cada paso, sustituye el acumulador por el resultado de la función.

val xs = List(1, 2, 3, 4)
val total = xs.foldLeft(0)((acc, x) => acc + x)

@main def run(): Unit =
  println(total)  // 10

Cómo asocia foldLeft

foldLeft agrupa desde la izquierda. Para List(1, 2, 3) con la semilla z, calcula f(f(f(z, 1), 2), 3).

El acumulador es el argumento izquierdo, por lo que se acumula mientras avanza hacia la derecha por la lista.

// List(1, 2, 3).foldLeft(0)(_ + _)
// = ((0 + 1) + 2) + 3
// = 6

Conceptos básicos de foldRight

foldRight también combina elementos, pero comienza por la derecha.

Su función recibe (element, acc), con el elemento a la izquierda y el acumulador a la derecha.

val xs = List(1, 2, 3, 4)
val total = xs.foldRight(0)((x, acc) => x + acc)

@main def run(): Unit =
  println(total)  // 10

Cómo asocia foldRight

foldRight agrupa desde la derecha. Para List(1, 2, 3) con la semilla z, calcula f(1, f(2, f(3, z))).

La semilla se sitúa en el extremo derecho y la lista se combina hacia dentro desde el final.

// List(1, 2, 3).foldRight(0)(_ + _)
// = 1 + (2 + (3 + 0))
// = 6

Cuándo importa la dirección

Para operaciones asociativas y conmutativas, como la suma o el producto, ambos plegados dan el mismo resultado.

Para operaciones no conmutativas, como la resta o la construcción de listas, la dirección cambia el resultado. Elija de forma deliberada.

val xs = List(1, 2, 3)
val l = xs.foldLeft(0)(_ - _)   // ((0-1)-2)-3 = -6
val r = xs.foldRight(0)(_ - _)  // 1-(2-(3-0)) = 2

@main def run(): Unit =
  println((l, r))  // (-6, 2)

Construir una lista

foldRight es la opción natural para reconstruir una lista en orden, porque trabaja desde la cola hacia dentro y anteponer mantiene los elementos en su posición.

Esto transforma cada elemento conservando el orden.

val xs = List(1, 2, 3)
val doubled = xs.foldRight(List.empty[Int]) { (x, acc) =>
  (x * 2) :: acc
}

@main def run(): Unit =
  println(doubled)  // List(2, 4, 6)

foldLeft invierte

Si construye una lista con foldLeft y antepone elementos, el resultado aparece invertido, porque los elementos se añaden al principio mientras se avanza hacia la derecha.

A veces esto es exactamente lo que necesita.

val xs = List(1, 2, 3)
val rev = xs.foldLeft(List.empty[Int]) { (acc, x) =>
  x :: acc
}

@main def run(): Unit =
  println(rev)  // List(3, 2, 1)

Seguridad de la pila

foldLeft es recursivo de cola y se ejecuta como un bucle, por lo que es seguro con colecciones enormes.

foldRight sobre una List no es recursivo de cola y puede desbordar la pila con listas muy largas. Prefiera foldLeft cuando no necesite un orden de derecha a izquierda.

// Safe even for millions of elements:
val n = (1 to 1000000).foldLeft(0L)(_ + _)

// foldRight on a long List risks StackOverflowError

Cambiar el tipo del resultado

El tipo del acumulador puede diferir del tipo de los elementos.

Aquí plegamos una lista de enteros para obtener una cadena, por lo que la semilla es una cadena vacía y cada paso añade contenido.

El tipo del plegado viene determinado por la semilla.

val xs = List(1, 2, 3)
val s = xs.foldLeft("")((acc, x) => acc + x.toString)

@main def run(): Unit =
  println(s)  // "123"

Fold como herramienta multiuso

Muchas operaciones sobre listas son casos particulares de fold: sum, product, length, max, map, filter y reverse.

Reconocer el fold que subyace a ellas le ayuda a escribir código conciso y declarativo en lugar de implementar la recursión manualmente.

val xs = List(4, 1, 7, 3)
val maxV = xs.foldLeft(Int.MinValue)(_ max _)
val len  = xs.foldLeft(0)((acc, _) => acc + 1)

@main def run(): Unit =
  println((maxV, len))  // (7, 4)

Comprobación rápida

Razone sobre la dirección del fold y la posición de la semilla.

Recapitulación

foldLeft recorre de izquierda a derecha con el acumulador a la izquierda y calcula ((z op a) op b) op c. Es recursivo de cola y seguro para la pila.

foldRight recorre de derecha a izquierda con la semilla a la derecha y calcula a op (b op (c op z)). Es adecuado para construir listas conservando el orden, pero puede desbordar la pila con listas largas.

La semilla determina el tipo del resultado, por lo que los folds pueden transformar una colección en cualquier valor.

Preguntas frecuentes

¿La lección «foldLeft y foldRight» es gratis?

Sí — el texto completo de «foldLeft y foldRight» 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 «foldLeft y foldRight»?

Reduzca colecciones a un valor 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 «foldLeft y foldRight»?

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

  1. Pensamiento recursivo
  2. Patrones de acumuladores
  3. foldLeft y foldRight
  4. reduce y aggregate
← Volver a Scala for Backend Engineering & Functional Programming