0

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?

5
  • 1
    converting List[(Int,String)] into List[Int] is just doing a .map(_._1) Commented Jun 2, 2018 at 14:04
  • @RameshMaharjan thanks a lot Commented Jun 2, 2018 at 14:15
  • did you get it solved? Commented Jun 2, 2018 at 14:33
  • Possible duplicate of Cleaner tuple groupBy Commented Jun 2, 2018 at 14:53
  • 1
    @RameshMaharjan yeah l.groupBy(x => x._2).mapValues[List[Int]](f => f.map(_._1)) works great Commented Jun 4, 2018 at 9:21

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

According to the source code, foldRight is implemented via foldLeft and neither one of them are recursive (tail or otherwise).
I know that all methods are implemented in imperative style, but I didn't know that foldRight is implemented as reverse.foldLeft. So, thank you for clarifying!
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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.