scala flatten List(List(List(String,List(String,String)

时间:2015-03-05 09:16:17

标签: scala

模式匹配后,来自mongo casbas的BasicDBobject得到类似的东西:

val arr = List(Some(None), 
               List(List(Some(None),
                         Some(None),
                         Some("54c22f3369702d7fdb8c0100"),
                         Some(None),
                         Some(None),
                         Some(None),
                         Some(None)),
                    List(Some(None), 
                         Some(None),
                         Some("54c22f3369702d7fdb8c0100"),
                         Some(None),
                         Some(None),
                         Some(None), 
                         Some(None)),
                    List(Some(None),
                         Some(None),
                         Some("54c22f3369702d7fdb8c0100"),
                         Some(None),
                         Some(None),
                         Some(None),
                         Some(None))),
                    Some(None))

我需要在List(Some(none), Some(string) ..)中将其展平在一个列表中。我怎么能做到这一点?

示例我需要从arr:

    List( Some("54c22f3369702d7fdb8c0100"), 
Some("54c22f3369702d7fdb8c0100"),  
Some("54c22f3369702d7fdb8c0100") )

我得到这个代码:

val subjectUsers = x.map {
        case ("entries", y: BasicDBList) => y(0) match {
          case entries: BasicDBList => entries.toList map {
            case z: BasicDBObject => z.toList map {
              case ("type", "subscribe") => Some(z("subject_id"))
              case ("info", v: BasicDBObject) => Some(v("user"))
              case _ => Some(None)
            }
            case _ => Some(None)
          }
        }
        case _ => Some(None)
      }.toList

我只需要像

这样的List(字符串)
List( Some("54c22f3369702d7fdb8c0100"), Some("54c22f3369702d7fdb8c0100"))

1 个答案:

答案 0 :(得分:1)

如果这是一个真正的任意结构,您可以使用shapeless' everything combinator以类型安全的方式收集所有Some[String]。只有在编译时拥有所有类型信息时,这才有效。如果要根据运行时类型执行此操作,最佳方法可能是模式匹配的递归函数:

def extractSomeStrings(a: Any): List[Some[String]] = a match {
  case l: List[_] => l flatMap extractSomeStrings
  case None => List()
  case Some(x) => x match {
    case s: String => List(Some(s))
  }
}

如果列表中包含MatchError s,ListNone以外的任何内容,那么(故意)抛出Some[String] - 如果您还有其他情况可以添加case来处理它们。