我有簡單的層次斯卡拉列表覆蓋到cortage
class A
case class B extends A
case class C extends A
case class D extends A
而且需要功能
def f(list: List[A]) : (List[B], List[C], List[D]) = ???
我可以收集B,C,d在muttable名單,但我想它在fucntional風格寫
我有簡單的層次斯卡拉列表覆蓋到cortage
class A
case class B extends A
case class C extends A
case class D extends A
而且需要功能
def f(list: List[A]) : (List[B], List[C], List[D]) = ???
我可以收集B,C,d在muttable名單,但我想它在fucntional風格寫
對於我來說,在這種情況下使用帶有列表的累加器是相當理想的:
case class Cortage(bs: List[B], cs: List[C], ds: List[D]) {
def asCortage = (bs, cs, ds)
}
def f(list: List[A], acc: Cortage = Cortage(List(), List(), List())): (List[B], List[C], List[D]) =
list match {
case x :: t => f(t,
x match {
case x:B => acc.copy(bs = x :: acc.bs)
case x:C => acc.copy(cs = x :: acc.cs)
case x:D => acc.copy(ds = x :: acc.ds)
})
case Nil => acc.asCortage
}
什麼可能比舊的Foldable
功能更多std
scalaz好友的庫實例。
import scalaz.syntax.foldable._
import scalaz.std.tuple._
import scalaz.std.list._
def f(list: List[A]) = list foldMap {
case b: B => (List(b), Nil, Nil)
case c: C => (Nil, List(c), Nil)
case d: D => (Nil, Nil, List(d))
}
然而要注意長名單注意到追加要素相當不錯,所以多一點點有效的實現可能是
import scalaz.syntax.foldable._
import scalaz.std.tuple._
import scalaz.std.vector._
import scalaz.std.list._
import scalaz.syntax.std.tuple._
def f(list: List[A]) = list foldMap {
case b: B => (Vector(b), Vector(), Vector())
case c: C => (Vector(), Vector(c), Vector())
case d: D => (Vector(), Vector(), Vector(d))
} mapElements (_.toList, _.toList, _.toList)
另一個變化
list.foldLeft((List.empty[B], List.empty[C],List.empty[D])) { case ((bs, cs, ds), a) =>
a match {
case x: B => (x :: bs, cs, ds)
case x: C => (bs, x :: cs, ds)
case x: D => (bs, cs, x :: ds)
}
}
因爲我不能發表評論答案,我提供了我的解決方案,其中 保留了訂單幷包括A的情況。
def f(xs: List[A]): (List[B], List[C], List[D]) = {
@tailrec
def group(xs: List[A], bs: List[B], cs: List[C], ds: List[D]): (List[B], List[C], List[D]) = xs match {
case Nil => (bs.reverse, cs.reverse, ds.reverse)
case (b: B) :: t => group(t, b :: bs, cs, ds)
case (c: C) :: t => group(t, bs, c :: cs, ds)
case (d: D) :: t => group(t, bs, cs, d :: ds)
case _ :: t => group(t, bs, cs, ds)
}
group(xs, List(), List(), List())
}
非常好的解決方案 – punksta