Play Framework 2.4.1:如何从 JsArray 中移除元素
Posted
技术标签:
【中文标题】Play Framework 2.4.1:如何从 JsArray 中移除元素【英文标题】:Play Framework 2.4.1: How to remove an element from a JsArray 【发布时间】:2015-06-29 18:54:16 【问题描述】:鉴于以下 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
中删除一个元素?
【问题讨论】:
【参考方案1】:JsValue
和 JsPath
中没有任何内容,您可以使用镜头库,例如 Monocle。否则,这是一种方法:
(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。)
【讨论】:
【参考方案2】:标准集合库中没有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
这将允许您为任何Traversable
分机(例如List
、Seq
、Iterable
等)拨打myCollection.dropAt(n)
。
当您使用 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
方法。
另一种选择是使用上面显示的丰富我的库模式将dropAt
方法直接添加到JsArray
(甚至JsValue
)。
如果需要转回JsArray
,可以使用Json.arr
方法。
【讨论】:
【参考方案3】:您可以通过将元素转换为可变集合而不是不可变列表来删除元素。在可变集合上,您可以调用将修改集合的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
【讨论】:
以上是关于Play Framework 2.4.1:如何从 JsArray 中移除元素的主要内容,如果未能解决你的问题,请参考以下文章
Play Framework 2.4.1:在测试模式下忽略 play.application.loader 设置
Play Framework Project:如何从源代码中包含插件
使用 Play Framework for Java,如何从控制器返回 500 响应?
如何在 Play Framework 1.2 中实现 HTTP Basic Auth?