我有以下问题,我不确定如何优雅地建模:
说我有以下课程:
class A(v: String)
class B(v: String, as: Seq[A])
class C(v: String, bs: Seq[B])
给定C
的实例我想为C
x B
x A
的每个组合生成一个值。即使C
实例没有任何B
或B
实例没有任何A
,我也希望生成一个值。
为简单起见,假设我想要生成的值是c.v - b.v - a.v
形式的字符串。
换句话说 - 我正在寻找一种方法来实现以下方法:
def produce(c: C): List[String] = ???
这样:
val c1 = new C(v = "c1", bs = Seq.empty)
produce(c1) // List("c1 - - ")
val c2 = new C(
v = "c1",
bs = Seq(new B(v = "b1", as = Seq.empty), new B(v = "b2", as = Seq.empty))
)
produce(c2) // List("c1 - b1 - ", "c1 - b2 - ")
val c3 = new C(
v = "c1"
bs = Seq(
new B(v = "b1", as = Seq(new A("a1"), new A("a2)))
new B(v = "b2", as = Seq(new A("a3"), new A("a4))),
)
)
produce(c3) // List("c1 - b1 - a1",
// "c1 - b1 - a2",
// "c1 - b2 - a3",
// "c1 - b2 - a4")
我尝试使用for comprehension来实现这一点,但由于flatMap
空Seq
没有产生值,我必须将空Seq
变成非空的public class myViewModel
{
public int Number1 {get; set;}
public int Number2 {get; set;}
public int Number3 {get; set;}
public int Number4 {get; set;}
}
。代码变得复杂而冗长。
我的问题是,最好的方法是什么?是否有一些数据结构可以帮助简化这一过程?
感谢。
答案 0 :(得分:2)
我认为这可以追溯到你所追求的目标。我将您的类转换为案例类,以使模式匹配更容易。
sealed abstract class VSet
case class A(v: String) extends VSet
case class B(v: String, as: Seq[A]) extends VSet
case class C(v: String, bs: Seq[B]) extends VSet
def produce(vset: VSet, prefix: String = ""): Seq[String] = vset match {
case C(v, bs) => if (bs.isEmpty) Seq(s"$v -")
else bs.flatMap(produce(_, s"$v => "))
case B(v, as) => if (as.isEmpty) Seq(s"$prefix$v -")
else as.flatMap(produce(_, s"$prefix$v => "))
case A(v) => Seq(s"$prefix$v")
}