简体   繁体   中英

Convert List[(Int,String)] into List[Int] in scala

My goal is to to map every word in a text (Index, line) to a list containing the indices of every line the word occurs in. I managed to write a function that returns a list of all words assigned to a index.

The following function should do the rest (map a list of indices to every word):

def mapIndicesToWords(l:List[(Int,String)]):Map[String,List[Int]] = ???

If I do this:

l.groupBy(x => x._2)

it returns a Map[String, List[(Int,String)] . Now I just want to change the value to type List[Int] . I thought of using .mapValues(...) and fold the list somehow, but I'm new to scala and don't know the correct approach for this.

So how do I convert the list?

Also you can use foldLeft, you need just specify accumulator (in your case Map[String, List[Int]]), which will be returned as a result, and write some logic inside. Here is my implementation.

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))
    }
  )

But with foldLeft, elements of list will be in reversed order, so you can use foldRight. Just change foldLeft to foldRight and swap input parameters, (map, entry) to (entry, map) .

And be careful, foldRight works 2 times slower. It is implemented using method reverse list and foldLeft.

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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM