Saltar al contenido

diferencia entre foldLeft y reduceLeft en Scala

Esta es la respuesta más completa que encomtrarás aportar, pero estúdiala detenidamente y analiza si se puede adaptar a tu proyecto.

Solución:

Algunas cosas para mencionar aquí, antes de dar la respuesta real:

  • Tu pregunta no tiene nada que ver con leftse trata más bien de la diferencia entre reducir y plegar
  • La diferencia no es la implementación en absoluto, solo mire las firmas.
  • La pregunta no tiene nada que ver con Scala en particular, se trata más bien de los dos conceptos de programación funcional.

Volviendo a tu pregunta:

Aquí está la firma de foldLeft (también podría haber sido foldRight para el punto que voy a hacer):

def foldLeft [B] (z: B)(f: (B, A) => B): B

Y aquí está la firma de reduceLeft (otra vez la dirección no importa aquí)

def reduceLeft [B >: A] (f: (B, A) => B): B

Estos dos se ven muy similares y por lo tanto causaron la confusión. reduceLeft es un caso especial de foldLeft (que por cierto significa que usted algunas veces puede expresar lo mismo usando cualquiera de ellos).

Cuando usted llama reduceLeft decir en un List[Int] literalmente reducirá toda la lista de enteros a un solo valor, que será del tipo Int (o un supertipo de Intpor eso [B >: A]).

Cuando usted llama foldLeft decir en un List[Int] plegará toda la lista (imagínese enrollar una hoja de papel) en un solo valor, pero este valor no tiene que estar siquiera relacionado con Int (por eso [B]).

Aquí hay un ejemplo:

def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) 
   (resultingTuple, currentInteger) =>
      (currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)

Este método toma un List[Int] y devuelve un Tuple2[List[Int], Int] o (List[Int], Int). Calcula la suma y devuelve una tupla con una lista de enteros y su suma. Por cierto, la lista se devuelve al revés, porque usamos foldLeft en vez de foldRight.

Mire One Fold para gobernarlos a todos para obtener una explicación más detallada.

reduceLeft es solo un método de conveniencia. es equivalente a

list.tail.foldLeft(list.head)(_)

foldLeft es más genérico, puedes usarlo para producir algo completamente diferente de lo que pusiste originalmente. Mientras que reduceLeft solo puede producir un resultado final del mismo tipo o supertipo del tipo de colección. Por ejemplo:

List(1,3,5).foldLeft(0)  _ + _ 
List(1,3,5).foldLeft(List[String]())  (a, b) => b.toString :: a 

los foldLeft aplicará el cierre con el último resultado doblado (primera vez usando el valor inicial) y el siguiente valor.

reduceLeft por otro lado, primero combinará dos valores de la lista y los aplicará al cierre. A continuación combinará el resto de valores con el resultado acumulado. Ver:

List(1,3,5).reduceLeft  (a, b) => println("a " + a + ", b " + b); a + b 

Si la lista está vacía foldLeft puede presentar el valor inicial como un resultado legal. reduceLeft por otro lado, no tiene un valor legal si no puede encontrar al menos un valor en la lista.

Reseñas y calificaciones

Si haces scroll puedes encontrar los comentarios de otros administradores, tú todavía tienes el poder dejar el tuyo si te gusta.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *