如何改善这个功能?

时间:2018-06-06 13:59:57

标签: scala collections

假设我有一个类似的数据结构:

case class B(bx: Int)
case class A(ax: Int, bs: Seq[B])

我正在编写一个函数A => Seq[(Int, Option[Int])],如下所示:

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

看起来很有效,但我不喜欢分支。你会如何提高foo

2 个答案:

答案 0 :(得分:3)

另一个选项 - 添加一个辅助函数,它接受Seq[T]并返回Seq[Option[T]],其中输出从不为空 - 如果输入为空,则输出将具有结果中有一个None元素:

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

优点:

  • 真正的没有分支(包括getOrElse,这是一种分支,虽然更优雅)
  • 不重复构建元组(a.ax调用一次)
  • 很好地分离了关注点(构建一个永不空的列表与处理A和B)

答案 1 :(得分:2)

使用Option随播广告对象进行撰写。

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