【问题标题】:How to improve this function?如何改进这个功能?
【发布时间】:2018-06-06 13:59:56
【问题描述】:

假设我有一个这样的数据结构:

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

【问题讨论】:

    标签: scala collections


    【解决方案1】:

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

    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)

    【讨论】:

      【解决方案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)))
      

      【讨论】:

      • 你真的认为这段代码比原来的更好吗?
      • 这让用户来决定@volia17
      猜你喜欢
      • 2011-07-30
      • 2021-05-03
      • 1970-01-01
      • 2022-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多