Scala list of lists counts different elements for index of subscriptions
I have a list of lists with the following data
val list = List (List ("a", "b", "c"), List ("d", "e", "f"), List ("a", "a", "a"))
I want to get rid of how many different data I have in each position of the subscriptions
1 β List ("a", "d", "a")
2 β List ("b", "e", "a")
3 β List ("c", "f", "a")
Is there a way to do this? It doesn't need to be indexed, but I need a number of different values ββfor the sublist index, the result could be
2 // different values ββof a and d
3 // different values ββof b, e and a
3 // different values ββof c, f and a
source to share
As I noted in a comment on Jhonny Everson (almost to the right, but now removed), you can use transpose
to get a list of columns and then distinct
to remove duplicates:
scala> list.transpose.map(_.distinct.size)
res0: List[Int] = List(2, 3, 3)
This will throw an exception if all the lists are not the same size, but perhaps what you want.
source to share
scala> list.transpose.map(_.toSet.size)
res0: List[Int] = List(2, 3, 3)
The output list.transpose
is equal List(List(a, d, a), List(b, e, a), List(c, f, a))
, which gives you the structure you want and then match each List
with Set
to get the unique elements and count them.
If you need unique items for each position, you can use zipWithIndex
and cancel exits.
scala> list.transpose.map(_.distinct).zipWithIndex.map(t => t._2 -> t._1)
res1: List[(Int, List[String])] = List((0,List(a, d)), (1,List(b, e, a)), (2,List(c, f, a)))
source to share
Here is the code you wanted:
var lOfl = List(List.range(1,5), List(2,2,2,3), Nil)
//> lOfl : List[List[Int]] = List(List(1, 2, 3, 4), List(2, 2, 2, 3), List())
for {
l <- lOfl
} yield l.toSet.count(_ => true) //> res1: List[Int] = List(4, 2, 0)
An example Int list list is created as lOfl; for a loop, iterates through each Int list; toSet converts the list to set the duplicate exclusion. then the count function does as the name says everything. OR use Scala's most commonly used collection function (: P: P), a map as below,
lOfl.map(l => l.toSet.count(_ => true) ) //> res2: List[Int] = List(4, 2, 0)
source to share