Scala 以列表为键、字符串为值的地图展平
Posted
技术标签:
【中文标题】Scala 以列表为键、字符串为值的地图展平【英文标题】:Scala flatten a map with list as key and string as value 【发布时间】:2020-08-10 16:08:38 【问题描述】:我有一个特殊的情况,我想像这样声明简单的配置
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)
但我无法弄清楚如何将键列表扁平化为键,因此我得到了最终理想的形式。我该如何解决?
【问题讨论】:
这不是一个简单的配置,因为每个元组内部都有不同长度的元组(注意键类型是java.io.Serializable
)。如果你在内部数据中使用List
s 而不是元组,它会容易得多。
你是对的。将键声明为列表而不是元组并结合下面发布的答案,我能够得到我想要的结果。谢谢!
【参考方案1】:
如果您使用List
构造您的config
,则代码非常简单:
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】:您可以尝试以下解决方案:
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.mapdata => (data,v)
.toMap
【讨论】:
在你的第二个例子中,这里:case (k,v) => k.mapdata => (data,v).toMap
,toMap
实际上并没有改变任何东西。您可以安全地删除它并节省一些 CPU 周期。【参考方案3】:
我认为以上答案是很好的实用答案。如果您处于无法控制输入的情况,并且您被Tuple
s 而不是List
s 卡住,我会这样做:
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
的任何内容。
【讨论】:
【参考方案4】:通过使用内置的 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()
【讨论】:
以上是关于Scala 以列表为键、字符串为值的地图展平的主要内容,如果未能解决你的问题,请参考以下文章