Json Play Framework 2.4.1:如何从JsArray中删除元素

Json Play Framework 2.4.1:如何从JsArray中删除元素,json,scala,playframework,playframework-2.4,Json,Scala,Playframework,Playframework 2.4,给定以下JSON scala> val js = Json.parse("""{"key1": "value1", "key2": "value2","list":[{"item1": "value1"},{"item2": "value2"}]}""") js: play.api.libs.json.JsValue = {"key1":"value1","key2":"value2","list":[{"item1":"value1"},{"item2":"value2"}]} 。。

给定以下JSON

scala>  val js = Json.parse("""{"key1": "value1", "key2": "value2","list":[{"item1": "value1"},{"item2": "value2"}]}""")
js: play.api.libs.json.JsValue = {"key1":"value1","key2":"value2","list":[{"item1":"value1"},{"item2":"value2"}]}
。。。我得到
列表的第一个元素,如下所示:

scala> val l = (js \ "list").as[List[JsValue]]
l: List[play.api.libs.json.JsValue] = List({"item1":"value1"}, {"item2":"value2"})

scala> val first = l(0)
first: play.api.libs.json.JsValue = {"item1":"value1"}

。。。但是如何从给定索引的
列表中删除元素?

JsValue
JsPath
中没有任何内容。为此,可以使用透镜库,例如。否则,这里有一种方法:

(js \ "list").get match {
  case JsArray(items) => dropAt(items, 1)
}
其中
dropAt
为:

def dropAt[A](items: Seq[A], id: Int): Seq[A] =
  items.zipWithIndex.filter(_._2 != id).map(_._1)

dropAt
并不漂亮,但我不知道有什么好的API可以做到这一点。)

标准集合库中没有
dropAt
。您可以使用enrich my library模式添加一个。在丰富集合时,最好使用
CanBuildFrom
结构,这样可以保持强类型。您可以将
dropAt
实现为:

implicit class TraversableDropAt[A, Repr <: Traversable[A]](val xs: TraversableLike[A, Repr]) extends AnyVal {
  def dropAt[That](n: Int)(implicit cbf: CanBuildFrom[Repr, A, That]): That = {
    val bf = cbf()
    bf.sizeHint(xs.size - 1) 
    bf ++= xs.take(n)
    bf ++= xs.drop(n + 1)
    bf.result
  }
}
拥有
项目
集合后,可以对其使用新的
dropAt
方法

另一个选项是使用上面显示的丰富我的库模式,将
dropAt
方法直接添加到
JsArray
(甚至
JsValue


如果需要转换回
JsArray
,可以使用
Json.arr
方法。

可以通过将元素转换为可变集合而不是不可变列表来删除元素。在可变集合上,可以调用
remove(int:Index)
操作来修改集合。所以你的案子可以写成

val js = Json.parse("""{"key1": "value1", "key2": "value2","list":[{"item1": "value1"},{"item2": "value2"}]}""")
val l = (js \ "list").as[ArrayBuffer[JsValue]]

l.remove(0) // returns the removed element at index 0 but modifies the underlying collection l


val js = Json.parse("""{"key1": "value1", "key2": "value2","list":[{"item1": "value1"},{"item2": "value2"}]}""")
val l = (js \ "list").as[ArrayBuffer[JsValue]]

l.remove(0) // returns the removed element at index 0 but modifies the underlying collection l