How to improve this function?

戏子无情 提交于 2019-12-23 18:06:41

问题


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 getOrElse which is a kind of branching, albeit a more elegant one)
  • No repetition of building the tuple (a.ax called 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!