如何迭代嵌套对象的所有组合?

时间:2016-12-02 13:03:50

标签: scala

我有以下问题,我不确定如何优雅地建模:

说我有以下课程:

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实例没有任何BB实例没有任何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来实现这一点,但由于flatMapSeq没有产生值,我必须将空Seq变成非空的public class myViewModel { public int Number1 {get; set;} public int Number2 {get; set;} public int Number3 {get; set;} public int Number4 {get; set;} } 。代码变得复杂而冗长。

我的问题是,最好的方法是什么?是否有一些数据结构可以帮助简化这一过程?

感谢。

1 个答案:

答案 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")
}