Как преобразовать вложенные последовательности в последовательность кортежей? - PullRequest
0 голосов
/ 07 июня 2018

Это продолжение моего предыдущего вопроса .

Предположим, у меня сейчас такая структура данных:

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()))

Будет ли полезен монадный преобразователь в этом случае?

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Ваша базовая комбинация 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)))
  }
}
0 голосов
/ 07 июня 2018

Я считаю, что это делает то, что вам нужно - основываясь на предыдущем ответе на похожий вопрос:

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(_))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...