根据Scala中List of Future的条件创建地图

时间:2016-01-14 23:00:10

标签: scala dictionary

我有param类型Future[List[MyRes]]的方法。 MyRes有两个选项字段idname。现在我想创建idname的地图,如果两者都存在的话。我能够创建具有默认值的地图,如下所示,但我不想让默认值只是跳过具有空值的条目。

def myMethod(myRes: Future[List[MyRes]]): Future[Map[Long, String]] = {
  myRes.map (
    _.map(
      o =>
      (o.id match {
        case Some(id) => id.toLong
        case _ => 0L 
      }) ->
      (o.name match {
        case Some(name) => name
        case _ => ""
      })
  ).toMap)

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

您正在寻找collect:)

myRes.map {  
   _.iterator
    .map { r => r.id -> r.name }
    .collect { case(Some(id), Some(name) => id -> name }
    .toMap
}

如果您的MyRes件事是案例类,那么您不需要第一个.map

myRes.map { 
  _.collect { case MyRes(Some(id), Some(name)) => id -> name }
  .toMap
}

collect.map类似,但它需要一个PartialFunction,并跳过未定义它的元素。它有点像你的match语句但没有默认值。

<强>更新 如果我正确地阅读您的评论,并且您希望在任一字段为“无”时记录消息,collect对此无效,但您可以执行flatMap

 myRes.map {
   _.flatMap {
     case MyRes(Some(id), Some(name)) => Some(id -> name)
     case x => loger.warn(s"Missing fields in $x."); None
   }
   .toMap
 }

答案 1 :(得分:0)

试试这个:

((age = :age AND room = :room1) OR (room = :room2))

诀窍是使用def myMethod(myRes: Future[List[MyRes]]): Future[Map[Long, String]] = { myRes.map ( _.flatMap(o => (for (id <- o.id; name <- o.name) yield (id.toLong -> name)).toList ).toMap ) } 展开List[Option[(Long,String)]]并将flatMap转换为Option