2016-11-13 72 views
0

在Scala中,如果我們有多重映射它映射字符串設置[字符串],例如:反轉Multimap之以功能性的方式在斯卡拉

val a = Map(
    "Account1" -> Set("Cars", "Trucks"), 
    "Account2" -> Set("Trucks", "Boats") 
) 

什麼是反相/倒車它與最終的一種優雅的方式:

Map(
    "Boats" -> Set("Account2"), 
    "Cars" -> Set("Account1"), 
    "Trucks" -> Set("Account1", "Account2") 
) 

回答

0

很抱歉的長眼線,你可以打破它,這僅僅是一個快速&骯髒的解決方案,但它確實工作

scala> a.toList.flatMap{ case (k,v:Set[_]) => v map (x => (x,k))}.groupBy(_._1).map{ case (k,v:List[(String,String)]) => (k,v.map(_._2).toSet)} 
res45: scala.collection.immutable.Map[String,scala.collection.immutable.Set[String]] = Map(Boats -> Set(Account2), Trucks -> Set(Account1, Account2), Cars -> Set(Account1)) 

,或者如果你喜歡閱讀的版本(同上述只是擊穿線路):):

scala> val aTuples = a.toList.flatMap{ case (k,v:Set[_]) => v map (x => (x,k))} 
aTuples: List[(String, String)] = List((Cars,Account1), (Trucks,Account1), (Trucks,Account2), (Boats,Account2)) 

scala> val grouped = aTuples.groupBy(_._1) 
grouped: scala.collection.immutable.Map[String,List[(String, String)]] = Map(Boats -> List((Boats,Account2)), Trucks -> List((Trucks,Account1), (Trucks,Account2)), Cars -> List((Cars,Account1))) 

scala> val flattenAndToSet = grouped.map{ case (k,v:List[(String,String)]) => (k,v.map(_._2).toSet)} 
flattenAndToSet: scala.collection.immutable.Map[String,scala.collection.immutable.Set[String]] = Map(Boats -> Set(Account2), Trucks -> Set(Account1, Account2), Cars -> Set(Account1)) 
+1

感謝。我已經從你的答案中學到了一些東西,並改變了我的想法(使用「zip」作爲元組)以達到這3行。我之前有5個更詳細的行,所以我感謝你的幫助。 val aTuples = a.toList.flatMap(t => List.fill(t._2.size)(t._1)zip t._2) val grouped = aTuples.map(_。swap).groupBy( _._ 1) VAL flattenAndToSet = grouped.map {情況下(K,v:列表[(字符串,字符串)])=>(K,v.map(_._ 2).toSet)}' 我會如果我們很快沒有更短的東西,請將您的解決方案標記爲答案。我希望「動態混入MultiMap特質(我無法讓它工作!),然後調用.invert」:) –