How to extract only the values from a map - scala

I have the following Map after doing a groupBy and then partition/sliding on an List of Lists. Now i'm only interested in the values of the map, the keys are irrelevant. Basically i'm trying to extract the subset of Lists after groupBy and sliding/partition and perform additional map and reduce functions on them.
var sectionMap : Map[Int,List[List[Any]]] = Map(
1 -> List(List(1,20,"A"), List(1,40,"B")),
2 -> List(List(2,30,"A"), List(2,80,"F")),
3 -> List(List(3,80,"B"))
)
I used sectionMap.values but it returned a format like Iterable[List[List[Any]]] However I want the following type List[List[Any]]. Is there is one step function to apply to achieve the result?
List(
List(1,20,"A"),
List(1,40,"B"),
List(2,30,"A"),
List(2,80,"F"),
List(3,80,"B")
)

You can use sectionMap.values.flatten.toList.
flatten convert types like Seq[Seq[T]] to Seq[T] and toList convert Iterable to List

you need to do map.values which will gives you the List of values. As values are List of List you will get Iterable(List(List(1,20,"A"))) :Iterable[List[List[Any]]] like this so you can do flatten to make it Iterable(List(1,20,"A")): Iterable[List[Any]].
If you want it to be List[List[Any]] do .toList after flatten.
you can use:
sectionMap.values.flatten
//output List(List(1, 20, A), List(1, 40, B), List(2, 30, A), List(2, 80, F), List(3, 80, B))

Using map or flatMap or collect method on sectionMap as below:
sectionMap.map(_._2).flatten.toList
sectionMap.flatMap(_._2).toList
sectionMap.collect{case (x,y) => y}.flatten.toList

You can also use flatMap:
sectionMap.flatMap{ case (_, x) => x }.toList
It combines flattening and extraction into the same iteration.

Related

Transformation of List[(Object1,Object2)] to Map[Object1, List[Object2]] - Scala

I have a list of pairs of objects Object1 and Object2.
I want to transform this list into a Map[Object1, List[Object2]].
Until now I implemented this one:
dictionary map (w => (wordOccurrences(w), w))
groupBy(identity).mapValues(_._2).toMap
but it doesn't work.
The mapValues are Lists. You need to traverse each List in order to un-tuple each element.
You'll also need to isolate the key, "Object1", from each tuple.
No toMap required. groupBy produces a Map already.
...groupBy(_._1).mapValues(_.map(_._2))
A convenient way is to use map/case. Note the curly brackets:
val plist = List((1, 1), (2, 4), (3, 9))
plist.toMap map {case (a, b) => (a -> List (b))}

How to implement GetResult[List[String]] in scala slick?

I'm use SQLActionBuilder, such as seq"""select ...""", to create a common/wide sql query and I not care about the result column count it is.
Document example use as[TupleX] to decided result type,in my stage, I want use List[String] replace TupleX type.
I have attempted with sQLActionBuilder.as[List[String]] but a compile error encounter:
Error:(8, 187) could not find implicit value for parameter rconv: slick.jdbc.GetResult[List[String]]
val x = reportUtilRepository.find(List())("td_report_region")(1469635200000L, 1475251200000L)("region" :: Nil, "clicks" :: "CPC" :: Nil)(List("1", "2"), List("regionType" -> "1"))(_.as[List[String]]).map(x => println(x.toString))
and sQLActionBuilder.as[List[(String, String, String)]] works well. So how can I use List[String] to match a common result.
I think a straight way is implement a GetResult[List[String]] as compiler tips but I don't know how to do it.Other ways also welcome.
Thanks.
First of all querying database always returns a list of tuples, so the result type will be List[TupleX] because each row is represented as a list record and then columns in each row are respectively tuple elements.
Therefore, your data will look like List((1,2,3),(3,4,5)) where data type is List[(Int, Int, Int)]. To produce List[Int] you might do following:
val a = List((1,2,3),(3,4,5))
a map {x => List(x._1, x._2, x._3)} flatten
res0: List[Int] = List(1, 2, 3, 3, 4, 5)

andThen in List scala

Has anyone got an example of how to use andThen with Lists? I notice that andThen is defined for List but the documentations hasn't got an example to show how to use it.
My understanding is that f andThen g means that execute function f and then execute function g. The input of function g is output of function f. Is this correct?
Question 1 - I have written the following code but I do not see why I should use andThen because I can achieve the same result with map.
scala> val l = List(1,2,3,4,5)
l: List[Int] = List(1, 2, 3, 4, 5)
//simple function that increments value of element of list
scala> def f(l:List[Int]):List[Int] = {l.map(x=>x-1)}
f: (l: List[Int])List[Int]
//function which decrements value of elements of list
scala> def g(l:List[Int]):List[Int] = {l.map(x=>x+1)}
g: (l: List[Int])List[Int]
scala> val p = f _ andThen g _
p: List[Int] => List[Int] = <function1>
//printing original list
scala> l
res75: List[Int] = List(1, 2, 3, 4, 5)
//p works as expected.
scala> p(l)
res74: List[Int] = List(1, 2, 3, 4, 5)
//but I can achieve the same with two maps. What is the point of andThen?
scala> l.map(x=>x+1).map(x=>x-1)
res76: List[Int] = List(1, 2, 3, 4, 5)
Could someone share practical examples where andThen is more useful than methods like filter, map etc. One use I could see above is that with andThen, I could create a new function,p, which is a combination of other functions. But this use brings out usefulness of andThen, not List and andThen
andThen is inherited from PartialFunction a few parents up the inheritance tree for List. You use List as a PartialFunction when you access its elements by index. That is, you can think of a List as a function from an index (from zero) to the element that occupies that index within the list itself.
If we have a list:
val list = List(1, 2, 3, 4)
We can call list like a function (because it is one):
scala> list(0)
res5: Int = 1
andThen allows us to compose one PartialFunction with another. For example, perhaps I want to create a List where I can access its elements by index, and then multiply the element by 2.
val list2 = list.andThen(_ * 2)
scala> list2(0)
res7: Int = 2
scala> list2(1)
res8: Int = 4
This is essentially the same as using map on the list, except the computation is lazy. Of course, you could accomplish the same thing with a view, but there might be some generic case where you'd want to treat the List as just a PartialFunction, instead (I can't think of any off the top of my head).
In your code, you aren't actually using andThen on the List itself. Rather, you're using it for functions that you're passing to map, etc. There is no difference in the results between mapping a List twice over f and g and mapping once over f andThen g. However, using the composition is preferred when mapping multiple times becomes expensive. In the case of Lists, traversing multiple times can become a tad computationally expensive when the list is large.
With the solution l.map(x=>x+1).map(x=>x-1) you are traversing the list twice.
When composing 2 functions using the andThen combinator and then applying it to the list, you only traverse the list once.
val h = ((x:Int) => x+1).andThen((x:Int) => x-1)
l.map(h) //traverses it only once

How to find the number of (key , value) pairs in a map in scala?

I need to find the number of (key , value) pairs in a Map in my Scala code. I can iterate through the map and get an answer but I wanted to know if there is any direct function for this purpose or not.
you can use .size
scala> val m=Map("a"->1,"b"->2,"c"->3)
m: scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2, c -> 3)
scala> m.size
res3: Int = 3
Use Map#size:
The size of this traversable or iterator.
The size method is from TraversableOnce so, barring infinite sequences or sequences that shouldn't be iterated again, it can be used over a wide range - List, Map, Set, etc.

Functional style in Scala to collect results from a method

I have two lists that I zip and go through the zipped result and call a function. This function returns a List of Strings as response. I now want to collect all the responses that I get and I do not want to have some sort of buffer that would collect the responses for each iteration.
seq1.zip(seq2).foreach((x: (Obj1, Obj1)) => {
callMethod(x._1, x._2) // This method returns a Seq of String when called
}
What I want to avoid is to create a ListBuffer and keep collecting it. Any clues to do it functionally?
Why not use map() to transform each input into a corresponding output ? Here's map() operating in a simple scenario:
scala> val l = List(1,2,3,4,5)
scala> l.map( x => x*2 )
res60: List[Int] = List(2, 4, 6, 8, 10)
so in your case it would look something like:
seq1.zip(seq2).map((x: (Obj1, Obj1)) => callMethod(x._1, x._2))
Given that your function returns a Seq of Strings, you could use flatMap() to flatten the results into one sequence.