【问题标题】:Deep flatten Scala Maps (or uJson Objs) - how to?深度展平 Scala Maps(或 uJson Objs) - 如何?
【发布时间】:2022-01-22 21:50:17
【问题描述】:

如何在 Scala 中展平深层嵌套的地图,返回一个新地图,其中包含点表示法的相关嵌套键?

背景:我正在尝试为 uJson.Objs 这样做,但由于它们只是 mutable.LinkedHashMap[String, Value] 的底层,标准库地图的答案也应该有所帮助。 p>

例如:

   val original = Obj("Simple" -> "a",
        "nested" ->
          Obj("c1" ->
            Obj("c2" -> "a")))
   
   flattenObj(original) shouldEqual Obj("simple" -> "a", "nested.c1.c2" -> "a")

我已经尝试了以下方法(基于this answer),但它仅适用于第一级,并且仍然不处理以点表示法命名新键:

    def flattenObj(o: Obj, delimiter: String = "."): Obj = {
      o.obj.flatMap {
        case (key, map: Obj) => map.obj
        case (key, value) => Map(key -> value)
      }
    }

结果:

Actual: {"Simple":"a","c1":{"c2":"a"}}

但是,我希望:

Expected: {"simple":"a","nested.c1.c2":"a"}

谢谢大家。

【问题讨论】:

  • 首先,您的解决方案应该是递归的。类似于def flattenObj(o: Obj, delimiter: String = ".", keyAcc: String=""): Obj = { o.obj.flatMap { case (key, map: Obj) => flattenObj(map.obj, keyAcc = keyAcc + "." + key) case (key, value) => Map(keyAcc + "." + key -> value) } }
  • 谢谢@Raf。请根据您的指导添加实施并且工作正常。我将发布并回答最终实现以帮助其他人。

标签: scala recursion functional-programming flatmap ujson


【解决方案1】:

基于@Raf 在 cmets 中的指导最终实现:

  def flattenObj(o: Obj, keyAcc: String = "", delimiter: String = "."): Obj = {
    o.obj.flatMap(kv => {
      val key: String = if (keyAcc.isEmpty) kv._1 else keyAcc + delimiter + kv._1

      kv._2 match {
        case map: Obj => flattenObj(map.obj, key, delimiter).obj
        case value => Map(key -> value)

      }
    })
  }

谢谢Raf

【讨论】:

    猜你喜欢
    • 2021-09-08
    • 2021-07-01
    • 1970-01-01
    • 2020-08-28
    • 2021-12-03
    • 2019-05-28
    • 2019-03-16
    • 2016-08-16
    • 2020-04-26
    相关资源
    最近更新 更多