我有一个我想映射到新集合的集合,但是每个结果值都取决于以某种方式之前的值。我可以用左侧解决此问题

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

这里的问题是我需要迭代整个列表以检索结果列表。假设我想要一个绘制遍历[a]的函数以遍历[b],并且只在我称之为成员时对成员进行评估?在我看来,这是一个相当传统的问题,所以我想知道是否有一种共同的方法。我目前拥有的是:

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

就功能纯度而言,您无法并行运行它,但否则听起来很听起来。

一个例子是;将每个元素归还给我,如果这是元素以前首次出现。

val elements:TraversableOnce[E]
val result = elements.mappyFoldyFunction(Set.empty[E]) {
 (s, e) => (s + e) -> (e -> s.contains(e))
}
result:TraversableOnce[(E,Boolean)]
有帮助吗?

解决方案

您也许可以利用国家单元。这是您的示例使用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)

其他提示

看起来您需要 seqview. 。利用 view 或者 view(from: Int, until: Int) 创建列表的非图案视图的方法。

我真的不明白您的榜样,因为您的检查总是会导致 false.

foldLeft 是不同的。它将通过汇总列表的所有元素来产生单个值。您显然需要 map (List => List).

无论如何,回答您关于懒惰的问题:您应该使用 Stream 代替 List. Stream 在实际调用之前,不要评估尾巴。

流API

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top