【问题标题】:Play Framework 2.4.1: How to remove an element from a JsArrayPlay Framework 2.4.1:如何从 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 中删除一个元素?

【问题讨论】:

    标签: json scala playframework playframework-2.4


    【解决方案1】:

    JsValueJsPath 中没有任何内容,您可以使用镜头库,例如 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 分机(例如ListSeqIterable 等)拨打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
        
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-14
          • 1970-01-01
          • 1970-01-01
          • 2012-11-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多