0

Given a List of JsObject's, I'd like to convert it to a Map[String, JsValue], and then iterate through each map's key-value pair, making a JsObject per pair. Finally, I'd like to put all of these JsObject's into a List[JsObject].

Below is my attempt with a for expression.

def getObjMap(obj: JsObject): Option[Map[String, JsValue]] = obj match { 
   case JsObject(fields) => Some(fields.toMap)
   case _ => None
}

def createFields(x: (String, JsValue)): JsObject = Json.obj("n" -> x._1, 
                                                            "v" -> x._2)    
val objects: List[JsObject] = foo()

val res: List[JsObject] = for {
                            obj <- objects
                            map <- getObjMap(obj)
                            mapField <- map
                          } yield(createFields(mapField))

However, I'm getting a compile-time error on the mapField <- map line.

[error] ...\myApp\app\services\Test.scala:65: type mismatch; 
[error]  found   : scala.collection.immutable.Iterable[play.api.libs.
                                                                  json.JsObject] 
[error]  required: Option[?]
4

1 回答 1

2

我认为问题出在这样一个事实,即 for 理解从处理一个 List 开始,然后最终处理一个 Option (from getObjMap)。为了理解,构造的类型需要在整体上保持不变。调用调用.toList的结果可以getObjMap解决这个问题:

val res: List[JsObject] = for {
                            obj <- objects
                            map <- getObjMap(obj).toList
                            mapField <- map
                          } yield(createFields(mapField))
于 2013-10-16T22:58:59.060 回答