在列表元素中反转映射到Scala中的String

时间:2018-01-04 04:17:48

标签: scala scala-collections

我是Scala的新手我试图压扁列表并反转映射。例如,我有一张地图如下:

Map("abc"->List(1,2,3),"def"->List(1,5,6))

我希望结果是:

Map(1->List("abc","def"),2->List("abc"),3->List("abc"),5->List("def"),6->List("def"))

实现这一目标的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

scala> val mm = Map("abc"->List(1,2,3),"def"->List(1,5,6))
mm.toList.flatMap{ case (s, l) => l.map(ll => (ll, s))}.groupBy(_._1).map{ case (i, l) => (i, l.map(_._2))}

mm: scala.collection.immutable.Map[String,List[Int]] = Map(abc -> List(1, 2, 3), def -> List(1, 5, 6))

scala> res9: scala.collection.immutable.Map[Int,List[String]] = Map(5 -> List(def), 1 -> List(abc, def), 6 -> List(def), 2 -> List(abc), 3 -> List(abc))

scala> 

更新: 我更喜欢稍微不同的解决方案:

mm.toList.flatMap{ case (s, l) => 
  l.map(li => (li, s))
}.foldLeft(Map.empty[Int, List[String]]){ 
  case (m, (i, s)) => m.updated(i, s :: m.getOrElse(i, List.empty))
}

答案 1 :(得分:0)

以下是您可以采用的简单方法

val data = Map("abc"->List(1,2,3),"def"->List(1,5,6))

val list = data.toList.flatMap(x => {
  x._2.map(y => (y, x._1))
}).groupBy(_._1).map(x => (x._1, x._2.map(_._2)))

输出:

(5,List(def))
(1,List(abc, def))
(6,List(def))
(2,List(abc))
(3,List(abc))

希望这有帮助!

答案 2 :(得分:0)

这是另外一种方法:

  Map("abc" -> List(1,2,3), "def"-> List(1,5,6)).flatMap {
    case (key, values) => values.map(elem => Map(elem -> key))
  }.flatten.foldRight(Map.empty[Int, List[String]]) { (elem, acc) =>
    val (key, value) = elem
    if (acc.contains(key)) {
      val newValues = acc(key) ++ List(value)
      (acc - key) ++ Map(key -> newValues)
    } else {
      acc ++ Map(key -> List(value))
    }
  }

所以基本上我所做的就是遍历初始Map,将其转换为元组,然后执行foldRight并将相同的键分组到累加器中。

这比这里发布的其他解决方案有点冗长,但我更愿意尽量避免在我的实现中使用下划线。

答案 3 :(得分:0)

另一种反转Map

的方法
val m = Map("abc" -> List(1, 2, 3), "def" -> List(1, 5, 6))

m.map{ case (k, v) => v.map((_, k)) }.flatten.
  groupBy(_._1).mapValues( _.map(_._2) )

// res1: scala.collection.immutable.Map[Int,scala.collection.immutable.Iterable[String]] = Map(
//   5 -> List(def), 1 -> List(abc, def), 6 -> List(def), 2 -> List(abc), 3 -> List(abc)
// )