scala:将List[Tuple3[A,B,C]]转换为Foo(A,B,List[C])的最短方法



我有一个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]] ],这会让我对结果进行平面映射,但不确定这能为我带来什么。

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

感谢

以下内容应该完全等效:

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

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

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

最新更新