Pergunta

Eu tenho uma coleção que quero mapear para uma nova coleção, no entanto, cada valor resultante depende do valor antes dele.

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

O problema aqui é que eu preciso iterar em toda a lista para recuperar a lista resultante. Digamos que eu queria uma função que mapeia o TraverSableOnce [A] para atravessar [B] e avaliar apenas os membros como eu os chamo? Parece -me ser um problema bastante convencional, por isso estou me perguntando se existe uma abordagem comum para isso. O que eu tenho atualmente é:

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
     }
   } 
}

No que diz respeito à pureza funcional, você não pode executá -lo em paralelo, mas, caso contrário, parece bom.

Um exemplo seria; Retorne -me cada elemento e, se for a primeira vez que o elemento aparece antes.

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

Solução

Você pode fazer uso da Mônada do Estado. Aqui está o seu exemplo reescrito usando o 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)

Outras dicas

Parece que você precisa Seqview. Usar view ou view(from: Int, until: Int) Métodos para criar uma visualização não rica da lista.

Eu realmente não entendo o seu exemplo, pois o seu contém cheque sempre resultará em false.

foldLeft é diferente. Isso resultará em um único valor agregando todos os elementos da lista. Você claramente precisa map (List => List).

Enfim, respondendo sua pergunta sobre preguiça: você deve usar Stream ao invés de List. Stream Não avalia a cauda antes de realmente chamá -la.

API do fluxo

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top