0

Let's say I have Scala list like this:

val mylist = List(4,2,5,6,4,4,2,6,5,6,6,2,5,4,4)

How can I transform it into list of count and list of element? For example, I want to convert mylist into:

val count = List(3,5,3,4)
val elements = List(2,4,5,6)

Which means, in mylist, I have three occurrences of 2, five occurrences of 4, etc.

In procedural, this is easy as I can just make two empty lists (for count and elements) and fill them while doing iteration. However, I have no idea on how to achieve this in Scala.

4 Answers 4

6

Arguably a shortest version:

 val elements = mylist.distinct
 val count = elements map (e => mylist.count(_ == e))
Sign up to request clarification or add additional context in comments.

Comments

4

Use .groupBy(identity) to create a Map regrouping elements with their occurences:

scala> val mylist = List(4,2,5,6,4,4,2,6,5,6,6,2,5,4,4)
mylist: List[Int] = List(4, 2, 5, 6, 4, 4, 2, 6, 5, 6, 6, 2, 5, 4, 4)

scala> mylist.groupBy(identity)
res0: scala.collection.immutable.Map[Int,List[Int]] = Map(2 -> List(2, 2, 2), 5 -> List(5, 5, 5), 4 -> List(4, 4, 4, 4, 4), 6 -> List(6, 6, 6, 6))

Then you can use .mapValues(_.length) to change the 'value' part of the map to the size of the list:

scala> mylist.groupBy(identity).mapValues(_.length)
res1: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3, 5 -> 3, 4 -> 5, 6 -> 4)

If you want to get 2 lists out of this you can use .unzip, which returns a tuple, the first part being the keys (ie the elements), the second being the values (ie the number of instances of the element in the original list):

scala> val (elements, counts) = mylist.groupBy(identity).mapValues(_.length).unzip
elements: scala.collection.immutable.Iterable[Int] = List(2, 5, 4, 6)
counts: scala.collection.immutable.Iterable[Int] = List(3, 3, 5, 4)

Comments

2

One way would be to use groupBy and then check the size of each "group":

val withSizes = mylist.groupBy(identity).toList.map { case (v, l) => (v, l.size) }
val count = withSizes.map(_._2)
val elements = withSizes.map(_._1)

Comments

0

You can try like this as well alternative way of doing the same.

Step - 1

scala> val mylist = List(4,2,5,6,4,4,2,6,5,6,6,2,5,4,4)

mylist: List[Int] = List(4, 2, 5, 6, 4, 4, 2, 6, 5, 6, 6, 2, 5, 4, 4)

// Use groupBy { x => x } returns a "Map[Int, List[Int]]"

step - 2

scala> mylist.groupBy(x => (x))

res0: scala.collection.immutable.Map[Int,List[Int]] = Map(2 -> List(2, 2, 2), 5 -> List(5, 5, 5), 4 -> List(4, 4, 4, 4, 4), 6 -> List(6, 6, 6, 6))

step - 3

scala> mylist.groupBy(x => (x)).map{case(num,times) =>(num,times.size)}.toList

res1: List[(Int, Int)] = List((2,3), (5,3), (4,5), (6,4))

step -4 - sort by num

scala> mylist.groupBy(x => (x)).map{case(num,times) =>(num,times.size)}.toList.sortBy(_._1)

res2: List[(Int, Int)] = List((2,3), (4,5), (5,3), (6,4))

step -5 - unzip to beak into to list it return tuple

scala> mylist.groupBy(x => (x)).map{case(num,times) =>(num,times.size)}.toList.sortBy(_._1).unzip res3: (List[Int], List[Int]) = (List(2, 4, 5, 6),List(3, 5, 3, 4))

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.