TransWikia.com

Scala, преобразовать Map[String, String] в Map[String, Any]

Stack Overflow на русском Asked by Bleser on January 4, 2022

Есть необходимость преобразовать:

Map(
  "a.b.c" -> "abc",
  "a.b.d" -> "abd"
)

в:

Map(
  "a" -> Map(
    "b" -> Map(
      "c"-> "abc",
      "d" -> "abd"
    )
  )
)

Пока что я смог добиться только следующей структуры:

List(Map("a" -> Map("b" -> Map("c" -> "abc"))), Map("a" -> Map("b" -> Map("d" -> "abd"))))

Но как это сплющить идей пока что нет.

UPD:
Немного измененый вариант из ответа который решает мою проблему.

def go(pairs: Map[Array[String], _]): Map[String, _] = {
    if (pairs.exists(_._1.length == 1)) pairs.map(t => t._1.head -> t._2)
    else {
      pairs
        .groupBy(_._1.head.toString)
        .mapValues { grouped =>
          val woGroupedKey = grouped.map { case (key, value) => key.tail -> value }
          go(woGroupedKey)
        }
    }
  }

One Answer

С рекурсией как-то так:

val original = Map("a.b.c" -> "abc", "a.b.d" -> "abd")

def go(pairs: Map[String, _]): Map[String, _] = {
  // если в ключе осталась одна буква - выходим
  if (pairs.exists(_._1.length == 1)) pairs
  else {
    pairs
      // группируем по первой букве
      .groupBy(_._1.head.toString)
      .mapValues { grouped =>
        // раз сгрупировали - уберём первую букву из ключа
        val woGroupedKey = grouped.map { case (key, value) => key.tail -> value }
        // пробуем ещё раз
        go(woGroupedKey)
      }
  }
}

// убираем точки, оставляем буквы
val woDots: Map[String, String] = original
  .map { case (key, value) => key.filter(_.isLetter) -> value }

go(woDots) // Map(a -> Map(b -> Map(c -> abc, d -> abd)))

Answered by EnverOsmanov on January 4, 2022

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP