2

我有一个 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
}

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

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

谢谢

4

2 回答 2

7

以下应该是完全等价的:

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)一个非空序列)。

于 2012-08-02T22:48:37.283 回答
4

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

res match {
  case (a, b, _) :: _ => Some(Invoices(a, b, res.map(_._3)))
  case _              => None
}
于 2012-08-02T23:42:18.540 回答