Melkor
Melkor

Reputation: 253

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?

Upvotes: 0

Views: 506

Answers (2)

Duelist
Duelist

Reputation: 1572

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.

Upvotes: 1

pedrorijo91
pedrorijo91

Reputation: 7865

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

Upvotes: 0

Related Questions