Scala Свести карту со списком в качестве ключа и строкой в ​​качестве значения - PullRequest
2 голосов
/ 27 апреля 2020

У меня есть особый случай, когда я хочу объявить простую конфигурацию, например, так:

val config = List((("a", "b", "c"), ("first")), 
               (("d", "e"), ("second")),
               (("f"), ("third")))

, которая во время выполнения, я хотел бы иметь карту, которая отображает как

"a" -> "first"
"b" -> "first"
"c" -> "first"
"d" -> "second"
"e" -> "second"
"f" -> "third"

Используя toMap, я смог преобразовать config в карту

scala> config.toMap
res42: scala.collection.immutable.Map[java.io.Serializable,String] = Map((a,b,c) -> first, (d,e) -> second, f -> third)

Но я не могу понять, как сгладить список ключей в ключи, чтобы я получил окончательный желательный сформироваться. Как мне это решить?

Ответы [ 4 ]

2 голосов
/ 27 апреля 2020

Если вы структурируете config, используя List, код очень прост:

val config = List(
  (List("a", "b", "c"), ("first")),
  (List("d", "e"), ("second")),
  (List("f"), ("third")))

config.flatMap{ case (k, v) => k.map(_ -> v) }.toMap
2 голосов
/ 27 апреля 2020

Вы можете попробовать решение ниже:

val config = List(
      (("a", "b", "c"), ("first")),
      (("d", "e"), ("second")),
      (("f"), ("third")))

val result = config.map {
  case (k,v) =>
    (
      k.toString().replace(")", "")
        .replace("(", "")
        .split(","), v)
  }

val res = result.map {
  case (key,value) => key.map{ data =>
    (data,value)
  }.toList
}.flatten.toMap

В случае, если вы измените структуру конфигурации на что-то вроде ниже, решение будет намного проще:

val config1 = List (
  (List("a", "b", "c"), "first"),
  (List("d", "e"), "second"),
  (List("f"), "third")
)


config1.flatMap{
  case (k,v) => k.map{data => (data,v)}
}.toMap
1 голос
/ 27 апреля 2020

Я думаю, что приведенные выше ответы являются хорошими практическими ответами. Если вы находитесь в ситуации, когда у вас нет контроля над вводом, и вы застряли с Tuple с вместо List с, я бы сделал это следующим образом:

val result: Map[String, String] = config.flatMap { 
  case (s: String, v) => List(s -> v)
  case (ks: Product, v) => ks.productIterator.collect { case s: String => s -> v }
  case _ => Nil //Prevent throwing
}.toMap

Это выбросит все, что не String в ключах.

0 голосов
/ 27 апреля 2020

с использованием встроенных функций Spark sql

val config = List((Array("a", "b", "c"), ("first")),
      (Array("d", "e"), ("second")),
      (Array("f"), ("third"))).toDF(List("col1","col2") : _*)

config.withColumn("exploded",functions.explode_outer($"col1")).drop("col1").show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...