我的目标是将文本中的每个单词(索引,行)映射到包含单词出现的每一行索引的列表。我设法编写一个函数,返回分配给索引的所有单词的列表。
以下函数应该完成其余的工作(将索引列表映射到每个单词):
def mapIndicesToWords(l:List[(Int,String)]):Map[String,List[Int]] = ???
如果我这样做:
l.groupBy(x => x._2)
它会返回Map[String, List[(Int,String)]
。现在我只想将值更改为List[Int]
类型。
我想过使用.mapValues(...)
并以某种方式折叠列表,但我是scala的新手,并且不知道正确的方法。
那么如何转换列表?
答案 0 :(得分:1)
你也可以使用foldLeft,你只需要指定累加器(在你的情况下是Map [String,List [Int]]),它将作为结果返回,并在里面写一些逻辑。这是我的实施。
def mapIndicesToWords(l:List[(Int,String)]): Map[String,List[Int]] =
l.foldLeft(Map[String, List[Int]]())((map, entry) =>
map.get(entry._2) match {
case Some(list) => map + (entry._2 -> (entry._1 :: list))
case None => map + (entry._2 -> List(entry._1))
}
)
但是使用foldLeft时,list的元素将按相反顺序排列,因此您可以使用foldRight。只需将foldLeft更改为foldRight并将输入参数(map, entry)
交换为(entry, map)
即可。
请注意,foldRight的工作速度要慢2倍。它使用方法反向列表和foldLeft实现。
答案 1 :(得分:0)
scala> val myMap: Map[String,List[(Int, String)]] = Map("a" -> List((1,"line1"), (2, "line")))
myMap: Map[String,List[(Int, String)]] = Map(a -> List((1,line1), (2,line)))
scala> myMap.mapValues(lst => lst.map(pair => pair._1))
res0: scala.collection.immutable.Map[String,List[Int]] = Map(a -> List(1, 2))