【问题标题】:scala: shortest way to convert List[ Tuple3[A,B,C] ] to Foo(A, B, List[C])scala:将 List[ Tuple3[A,B,C] ] 转换为 Foo(A, B, List[C]) 的最短方法
【发布时间】:2012-07-31 23:16:54
【问题描述】:

我有一个List[ Tuple3[User, Order, OrderItem] ]的查询结果

要创建 Invoice 的案例类实例,它的伴生对象需要一个 User、Order 和一个 List[OrderItem]。

目前我正在破解它:

def getInvoice(orderNum: String): Option[Invoice] = {

  val res = 
    dao.byOrderNum(orderNum) // List[ Tuple3[User, OrderEntry, OrderItem] ]

  if(!res.isEmpty) {
    val(user, order) = (res(0)._1, res(0)._2)
    val items = res map { case(_, _, oi: OrderItem) => oi }
    Some( Invoices.apply(user, order, items) ) // gets an Invoice
  }
  else None
}

我可以将查询结果设为List[ Option[Tuple3[User, Order, OrderItem]] ],这可以让我对结果进行平面映射,但不确定这对我有什么好处。

无论如何,必须是更简洁/优雅的问题解决方案

谢谢

【问题讨论】:

    标签: list scala mapping instance one-to-many


    【解决方案1】:

    headOption 东西很简洁,你不妨使用它,因为它在那里,但你可以简单地在 List 上进行模式匹配(而不是映射一个选项),这就是你的问题,但它只是需要整理一下:

    res match {
      case (a, b, _) :: _ => Some(Invoices(a, b, res.map(_._3)))
      case _              => None
    }
    

    【讨论】:

    • +1,这很荒谬,编译器怎么知道匹配元组List的第一行?我希望 case(a,b) 绑定到 List[A], List[B]
    • 如果resTuple3,则此代码可以正常工作,但因为它是List[Tuple3],所以它不起作用。
    • @virtualeyes :: 这是一个提取器对象,为提取列表提供了很好的语法。在模式匹配中,A(b, c)可以写成b A c,所以这和case ::((a, b, _), _) => ...是一样的。
    • @sschaef 你错过了提取器。
    • @LuigiPlinge 确实,我们都错过了 :: ;-) 在围栏上, headOption 我可以稍后再访问并知道发生了什么。 :: 几周后,不太确定(除非我经常使用它以使其根深蒂固)
    【解决方案2】:

    以下内容应该完全等价:

    def getInvoice(orderNum: String): Option[Invoice] = {
      val res = dao.byOrderNum(orderNum)
    
      res.headOption.map {
        case (user, order, _) => Invoices(user, order, res.map(_._3))
      }
    }
    

    关键是headOption,它以更惯用的方式处理空序列检查(它为空序列提供None,为非空序列提供Some(xs.head))。

    【讨论】:

    • 一般来说,使用 List[T] 结果与使用 List[ Option[T] ] 效果更好吗?我已经将我的 dao 的 list[T](query) 设置为返回 List[T],但不确定这是否会限制我/导致问题...
    • List[Option[T]] 的语义是什么?具体来说,None 是什么意思?
    • 确切地说,您可以对其进行 flatMap 以获得...List[T],也许最好首先从 List[T] 开始;-) 我正在使用 Option[T ] 用于单行结果,否则为 List[T]。该 headOption 将派上用场一对多的关系,感谢宝石!
    猜你喜欢
    • 2016-09-16
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    相关资源
    最近更新 更多