在Scala中变换贴图
我想在Scala中转换在Scala中变换贴图,scala,anonymous-function,scala-collections,Scala,Anonymous Function,Scala Collections,我想在Scala中转换String->List[String]类型的映射,这样每个(k,(List v1,v2,…vn))键值对都会导致对{(k:v1,k),(k:v2,k),…(k:vn,k)} 例如,我想转换 scala.collection.immutable.Map[String,List[String]] = Map(A -> List(a1, a2), B -> List(b1)) 到 我使用[这个答案][1]实现了我的目标: scala> val schema
String->List[String]
类型的映射,这样每个(k,(List v1,v2,…vn))
键值对都会导致对{(k:v1,k),(k:v2,k),…(k:vn,k)}
例如,我想转换
scala.collection.immutable.Map[String,List[String]] = Map(A -> List(a1, a2), B -> List(b1))
到
我使用[这个答案][1]实现了我的目标:
scala> val schema = Map("A" -> List("a1", "a2"), "B" -> List("b1"))
schema: scala.collection.immutable.Map[String,List[String]] = Map(A -> List(a1, a2), B -> List(b1))
scala> schema flatten {case(k, vs) => vs.map((_, k))}
res1: scala.collection.immutable.Iterable[(String, String)] = List((a1,A), (a2,A), (b1,B))
当我尝试为每个值预加原始键和冒号时,会出现一个错误:
scala> schema flatten {case(k, vs) => vs.map((k.concat(":").concat(_), k))}
<console>:13: error: type mismatch;
found : (String => String, String)
required: String => ?
schema flatten {case(k, vs) => vs.map((k.concat(":").concat(_), k))}
scala>schema展平{case(k,vs)=>vs.map((k.concat(“:”).concat(u),k))}
:13:错误:类型不匹配;
找到:(String=>String,String)
必需:字符串=>?
模式展平{case(k,vs)=>vs.map((k.concat(“:”).concat(u),k))}
(k.concat(“:”).concat(k),k)
中没有,也没有变量,因此它不是一个函数文本,但是映射的参数必须是一个函数
k
与k
连接起来schema.flatMap { case (k, vs) => vs.map(v => (k + ":" + v, k)) }
或者更简洁地说:
for ((k, vs) <- schema; v <- vs) yield (k + ":" + v, k)
用于((k,vs)字符串,字符串)
。这与String=>(String,String)
不同,这仍然不是您想要的
(k.concat(“:”).concat(k),k)
中没有,也没有变量,因此它不是一个函数文本,但是映射的参数必须是一个函数
k
与k
连接起来schema.flatMap { case (k, vs) => vs.map(v => (k + ":" + v, k)) }
或者更简洁地说:
for ((k, vs) <- schema; v <- vs) yield (k + ":" + v, k)
用于((k,vs)字符串,字符串)
。这与String=>(String,String)
不同,这仍然不是您想要的。错误消息告诉您,.map
采用String=>?
形式的函数,但您正在传递一个(String,String)
的元组
(k.concat(“:”)。concat(k),k)
不是一个函数-而且我认为你不是有意在concat
中放置k
两次
要创建映射,您需要一个带有签名的函数String=>(String,String)
错误地将vs.map((k.concat(“:”).concat(k,k))
传递到map(String,String)
错误地将vs.map((k.concat(“:”).concat(u),k))
传递到map(String=>String,String)
正确匹配vs.map(v=>(k.concat(“:”).concat(v,k))
String=>(String,String)
schema flatten {case(k, vs) => vs.map(v => (k.concat(":").concat(v), k)) }
// List((A:a1,A), (A:a2,A), (B:b1,B))
您可以看到此代码正在运行
然而,正如Andrey出色的评论所指出的,使用带有隐式函数的flatten
并不是一个好的实践。此外,您需要的是映射
,而不是列表
。出于这两个原因,我认为您应该使用flatMap
而不是flatte
:
schema flatMap {case(k, vs) => vs.map(v => (k.concat(":").concat(v), k)) };
// Map(A:a1 -> A, A:a2 -> A, B:b1 -> B)
查看是否要尝试。错误消息告诉您,
.map
采用String=>?
形式的函数,但您正在向它传递一个(String,String)
元组
(k.concat(“:”)。concat(k),k)
不是一个函数-而且我认为你不是有意在concat
中放置k
两次
要创建映射,您需要一个带有签名的函数String=>(String,String)
错误地将vs.map((k.concat(“:”).concat(k,k))
传递到map(String,String)
错误地将vs.map((k.concat(“:”).concat(u),k))
传递到map(String=>String,String)
正确匹配vs.map(v=>(k.concat(“:”).concat(v,k))
String=>(String,String)
schema flatten {case(k, vs) => vs.map(v => (k.concat(":").concat(v), k)) }
// List((A:a1,A), (A:a2,A), (B:b1,B))
您可以看到此代码正在运行
然而,正如Andrey出色的评论所指出的,使用带有隐式函数的flatten
并不是一个好的实践。此外,您需要的是映射
,而不是列表
。出于这两个原因,我认为您应该使用flatMap
而不是flatte
:
schema flatMap {case(k, vs) => vs.map(v => (k.concat(":").concat(v), k)) };
// Map(A:a1 -> A, A:a2 -> A, B:b1 -> B)
看看你是否想试试。
展平
?什么时候开始有人用flatten
代替flatMap
?@TimothyJonesflatten
没有什么错。但是滥用隐式函数参数使其表现得像一个flatMap
是非常丑陋的。应该记住,对于某些B
,这个隐式函数参数的存在只是为了通过将类型参数A
转换为Iterable[B]
使类型检查器满意。在没有隐式转换函数就可以表达此约束的严格类型化编程语言中,或者在非类型化语言中,flatte
甚至不接受任何参数<代码>展平应实现基本的一元“乘法”。不用担心,谢谢!我还注意到,在这种情况下,它会导致错误的返回类型。flatte
?什么时候开始有人用flatten
代替flatMap
?@TimothyJonesflatten
没有什么错。但是滥用隐式函数参数使其表现得像一个flatMap
是非常丑陋的。应该记住,对于某些B
,这个隐式函数参数的存在只是为了通过将类型参数A
转换为Iterable[B]
使类型检查器满意。在没有隐式转换函数就可以表达此约束的严格类型化编程语言中,或者在非类型化语言中,flatte
甚至不接受任何参数<代码>展平应实现基本的一元“乘法”。不用担心,谢谢!我还注意到,在这种情况下,它会导致错误的返回类型。谢谢。我确实在我的帖子中犯了一个错误,我在回复你的答案时纠正了这个错误。当我切换到(k.concat(“:”)。concat(uu),k)
时,我仍然会遇到一个错误,尽管是另一个错误。Andrey,非常感谢您的帮助