dirceusemighini
dirceusemighini

Reputation: 1354

Scala list of list count different elements per sublist index

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 disicover how many different data do I have in each position of the sublists

1 -> List("a","d","a")

2 -> List("b","e","a")

3 -> List("c","f","a")

Is there a way to do that? It doesn't need to be indexed, but I need the amount of different values per sublist index, the result could also be

2 // different values a and d

3 // different values b, e and a

3 // different values c, f and a

Upvotes: 3

Views: 747

Answers (3)

user3366706
user3366706

Reputation: 1599

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)

A sample list of list of Int is created as lOfl; for loop iterates through each list of Int; toSet converts list to set eliminating duplicate elements. then count function does as the name says it all. OR use the Scala's most used collection function (:P :P), map, like below,

  lOfl.map(l => l.toSet.count(_ => true) )       //> res2: List[Int] = List(4, 2, 0)

Upvotes: -1

Travis Brown
Travis Brown

Reputation: 139058

As I noted in a comment on Jhonny Everson's (almost right but now deleted) answer, you can use transpose to get a list of the 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 don't have the same size, but that's probably what you want.

Upvotes: 4

Brian
Brian

Reputation: 20295

scala> list.transpose.map(_.toSet.size)
res0: List[Int] = List(2, 3, 3)

The output of list.transpose is List(List(a, d, a), List(b, e, a), List(c, f, a)) which gives you the structure you want then map each List to a Set to get the unique elements and count them.

If you want unique elements per position, then you can use zipWithIndex and reverse the outputs.

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

Upvotes: 0

Related Questions