Scala中转换String->List[String]类型Map的需求及报错问题
搞定Scala的Map类型转换问题
我来帮你解决这个Map转换的需求!首先咱们明确目标:把Map[String, List[String]]里的每一组(k, List(v1, v2...)),拆成多个k:vi -> k的键值对,最终得到新的Map。
先说说你遇到的问题
你已经尝试用flatten实现基础的拆分组装,但在给值加前缀的时候报错了:
schema flatten {case(k, vs) => vs.map((k.concat(":").concat(_), k))}
这个错误的根源是Scala的语法解析问题:你写的(k.concat(":").concat(_), k)会被当成两个参数传给map,但map只接受一个函数参数(用来生成单个元素),所以就出现了类型不匹配的报错。
正确的实现方式
咱们只需要把要生成的元组明确包裹好,或者用Scala的字符串插值让代码更简洁,就能解决问题。这里给你两种好用的写法:
写法1:用flatMap+字符串插值
val schema = Map("A" -> List("a1", "a2"), "B" -> List("b1")) val convertedMap = schema.flatMap { case (key, values) => values.map(value => (s"$key:$value", key)) }.toMap
写法2:用for推导式(更直观)
如果你觉得flatMap的嵌套写法有点绕,用for推导式会更易读:
val schema = Map("A" -> List("a1", "a2"), "B" -> List("b1")) val convertedMap = (for { (key, values) <- schema value <- values } yield (s"$key:$value", key)).toMap
看看结果
运行上面的代码后,convertedMap就是你想要的结果:
scala.collection.immutable.Map[String,String] = Map(A:a1 -> A, A:a2 -> A, B:b1 -> B)
小补充
- 注意
flatMap返回的是Iterable[(String, String)],所以要调用.toMap把它转换成Map类型; - 字符串插值
s"$key:$value"比key.concat(":").concat(value)简洁太多,是Scala里推荐的字符串拼接方式; - 如果你用的是较老的Scala版本(2.12之前),字符串插值依然可以正常使用,不用担心兼容性。
内容的提问来源于stack exchange,提问作者Ellen Spertus
相关产品推荐
相关产品推荐

