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

时间:2015-06-29 18:54:16

标签: 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"}]}

...我得到list的第一个元素:

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"}

...但如何在给定索引处从list删除元素?

3 个答案:

答案 0 :(得分:1)

@Override public boolean onOptionsItemSelected(MenuItem menuItem) { if (menuItem.getItemId() == android.R.id.home) { onBackPressed(); } else { super.onOptionsItemSelected(menuItem); } return true; } JsValue中没有任何内容,您可以使用Monocle之类的镜头库。否则,这是一种方法:

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) 并不漂亮,但我不知道有什么好的API。)

答案 1 :(得分:1)

标准馆藏库中没有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
  }
}

这样,您就可以针对任何myCollection.dropAt(n)分机致电Traversable(例如ListSeqIterable等。)

当您使用PlayJSON类型时,您通常最好尽快将它们转换为普通的Scala类型。在这里,您可以通过多种方式将数组转换为Seq[JsValue]

val items = (js \ "list").as[Seq[JsValue]]
val items = (js \ "list").as[JsArray].value
val items = (js \ "list") match { case JsArray(items) => items }
val JsArray(items) = (js \ "list")

拥有items集合后,您可以使用新的dropAt方法。

另一种选择是使用上面显示的enrich-my-library模式将dropAt方法直接添加到JsArray(甚至JsValue)。

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

答案 2 :(得分:0)

您可以通过将元素转换为可变集合而不是不可变列表来删除元素。在可变集合上,您可以调用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