问题
Suppose I've got a data structure like that:
case class B(bx: Int)
case class A(ax: Int, bs: Seq[B])
I am writing a function A => Seq[(Int, Option[Int])] as follows:
def foo(a: A): Seq[(Int, Option[Int])] =
if (a.bs.isEmpty) Seq((a.ax, None)) else a.bs.map(b => (a.ax, Some(b.bx)))
It seems working but I don't like the branching. How would you improve foo ?
回答1:
Another option - add an auxiliary function that takes a Seq[T] and returns a Seq[Option[T]] where the output is never empty - if the input is empty, the output would have a single None element in its result:
def foo(a: A): Seq[(Int, Option[Int])] = toOptions(a.bs.map(_.bx)).map((a.ax, _))
// 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(_))
Benefits:
- This truly has no branching (including
getOrElsewhich is a kind of branching, albeit a more elegant one) - No repetition of building the tuple (
a.axcalled once) - Nice separation of concerns (building a never-empty list vs. dealing with A and Bs)
回答2:
Use Option companion object to compose.
def foo(a: A): Seq[(Int, Option[Int])] =
Option(a.bs).filterNot(_.isEmpty)
.map(list => list.map(b => (a.ax, Some(b.bx))))
.getOrElse(Seq((a.ax, None)))
来源:https://stackoverflow.com/questions/50722343/how-to-improve-this-function