2

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

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)
        }
    }
  }
Bleser
  • 1,758

1 Answers1

3

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

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)))

EnverOsmanov
  • 1,277
  • 1
    Хотя мне было нужно немного другое, но изменив пару строчек получил то что нужно. Спасибо! – Bleser Jul 24 '20 at 16:44