Pregunta

Tengo una colección que quiero asignar a una nueva colección, sin embargo, cada valor resultante depende del valor anterior de alguna manera. Podría resolver esto con un plomo izquierdo

val result:List[B] = (myList:List[A]).foldLeft(C -> List.empty[B]){ 
  case ((c, list), a) =>
    ..some function returning something like..
    C -> (B :: list)
} 

El problema aquí es que necesito iterar a través de toda la lista para recuperar la lista resultante. Digamos que quería una función que mapee TraversableUnce [A] para TraversableUnce [B] y solo evalúe a los miembros como yo los llamo? Me parece un problema bastante convencional, así que me pregunto si hay un enfoque común para esto. Lo que tengo actualmente es:

implicit class TraversableOnceEx[T](val self : TraversableOnce[T]) extends AnyVal {

   def foldyMappyFunction[A, U](a:A)(func:(A,T) => (A,U)):TraversableOnce[U] = {
     var currentA = a
     self.map { t =>
        val result = func(currentA, t)
        currentA = result._1
        result._2
     }
   } 
}

En cuanto a la pureza funcional, no podría ejecutarla en paralelo, pero de lo contrario parece sólido.

Un ejemplo sería; Devuélveme cada elemento y si es la primera vez que el elemento ha aparecido antes.

val elements:TraversableOnce[E]
val result = elements.mappyFoldyFunction(Set.empty[E]) {
 (s, e) => (s + e) -> (e -> s.contains(e))
}
result:TraversableOnce[(E,Boolean)]
¿Fue útil?

Solución

Es posible que pueda hacer uso de la mónada estatal. Aquí está su ejemplo reescrito usando Scalaz:

import scalaz._, Scalaz._

def foldyMappy(i: Int) = State[Set[Int], (Int, Boolean)](s => (s + i, (i, s contains(i))))

val r = List(1, 2, 3, 3, 6).traverseS(foldyMappy)(Set.empty[Int])._2

//List((1,false), (2,false), (3,false), (3,true), (6,false))
println(r)

Otros consejos

Parece que necesitas SeqView. Usar view o view(from: Int, until: Int) Métodos para crear una visión de la lista no rictamente.

Realmente no entiendo tu ejemplo ya que tu cheque contiene siempre dará como resultado false.

foldLeft es diferente. Dará como resultado un valor único al agregar todos los elementos de la lista. Claramente necesitas map (List => List).

De todos modos, respondiendo a su pregunta sobre la pereza: debe usar Stream en vez de List. Stream No evalúa la cola antes de llamarlo.

API de transmisión

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top