如何将嵌套序列转换为元组序列?

时间:2018-06-07 15:07:51

标签: scala collections

这是我之前question的后续内容。

假设我现在有这样的数据结构:

case class C()

case class B(cs: Seq[C])

case class A(bs: Seq[B])

你会如何写一个函数A => Seq[(A, Option[B], Option[C])]
该功能应该像这样工作:

A(Nil)              // Seq((Some(A()), None, None))
A(Seq(B(Nil)))      // Seq((Some(A()), Some(B()), None))
A(Seq(B(Seq(C())))) // Seq((Some(A()), Some(B()), Some(C()))

monad变压器在这种情况下是否有用?

2 个答案:

答案 0 :(得分:1)

我相信这可以满足您的需求 - 基于之前的answer类似问题:

def foo(a: A): Seq[(A, Option[B], Option[C])] =
  toOptions(a.bs).flatMap(optB =>
    optB
      .map(b => toOptions(b.cs))
      .getOrElse(Seq(None))
      .map(optC => (a, optB, optC))
  )

// always returns a non-empty list - with None as the only value for empty input
def toOptions[T](s: Seq[T]): Seq[Option[T]] = s.headOption +: s.drop(1).map(Some(_))

答案 1 :(得分:1)

您的基本map / flatMap组合,并对None条件进行额外测试。

def unwind(a:A) :Seq[(A, Option[B], Option[C])] = {
  if (a.bs.isEmpty) Seq((a,None,None))
  else a.bs.flatMap{ b =>
    if (b.cs.isEmpty) Seq((a,Some(b),None))
    else b.cs.map(c => (a,Some(b),Some(c)))
  }
}