Scala how can I count the number of entries in a list

val list = List(1,2,4,2,4,7,3,2,4) 

I want to implement it as follows: list.count(2) (returns 3).

+79
scala
Jul 12 '12 at 9:20
source share
15 answers

A slightly cleaner version of one of the other answers:

 val s = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges") s.groupBy(identity).mapValues(_.size) 

giving a Map counter for each element in the original sequence:

 Map(banana -> 1, oranges -> 3, apple -> 3) 

The question asks how to find the counter of a specific item. With this approach, the solution would require comparing the desired item with its count value as follows:

 s.groupBy(identity).mapValues(_.size)("apple") 
+121
Feb 13 '15 at 8:11
source share

scala collections have count : list.count(_ == 2)

+116
Jul 12 2018-12-12T00:
source share

I had the same problem as Sharath Prabhal, and I got another (clearer) solution:

 val s = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges") s.groupBy(l => l).map(t => (t._1, t._2.length)) 

As a result:

 Map(banana -> 1, oranges -> 3, apple -> 3) 
+41
Dec 02 '13 at 11:58
source share
 val list = List(1, 2, 4, 2, 4, 7, 3, 2, 4) // Using the provided count method this would yield the occurrences of each value in the list: l map(x => l.count(_ == x)) List[Int] = List(1, 3, 3, 3, 3, 1, 1, 3, 3) // This will yield a list of pairs where the first number is the number from the original list and the second number represents how often the first number occurs in the list: l map(x => (x, l.count(_ == x))) // outputs => List[(Int, Int)] = List((1,1), (2,3), (4,3), (2,3), (4,3), (7,1), (3,1), (2,3), (4,3)) 
+14
Jul 12 2018-12-12T00:
source share
 list.groupBy(i=>i).mapValues(_.size) 

gives

 Map[Int, Int] = Map(1 -> 1, 2 -> 3, 7 -> 1, 3 -> 1, 4 -> 3) 

Note that you can replace (i=>i) built-in identity function:

 list.groupBy(identity).mapValues(_.size) 
+13
Dec 13 '16 at 22:55
source share

I ran into the same problem, but wanted to count several items at a time ..

 val s = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges") s.foldLeft(Map.empty[String, Int]) { (m, x) => m + ((x, m.getOrElse(x, 0) + 1)) } res1: scala.collection.immutable.Map[String,Int] = Map(apple -> 3, oranges -> 3, banana -> 1) 

https://gist.github.com/sharathprabhal/6890475

+8
Oct 10 '13 at 13:25
source share

If you want to use it as list.count(2) , you must implement it using the Implicit class .

 implicit class Count[T](list: List[T]) { def count(n: T): Int = list.count(_ == n) } List(1,2,4,2,4,7,3,2,4).count(2) // returns 3 List(1,2,4,2,4,7,3,2,4).count(5) // returns 0 
+8
May 23 '15 at 19:49
source share

Short answer:

 import scalaz._, Scalaz._ xs.foldMap(x => Map(x -> 1)) 

Long answer:

The use of Scala is given.

 import scalaz._, Scalaz._ val xs = List('a, 'b, 'c, 'c, 'a, 'a, 'b, 'd) 

then all this (in order from less simplified to more simplified)

 xs.map(x => Map(x -> 1)).foldMap(identity) xs.map(x => Map(x -> 1)).foldMap() xs.map(x => Map(x -> 1)).suml xs.map(_ -> 1).foldMap(Map(_)) xs.foldMap(x => Map(x -> 1)) 

Give way

 Map('b -> 2, 'a -> 3, 'c -> 2, 'd -> 1) 
+7
Sep 17 '14 at 20:21
source share

It is interesting to note that a card with a default value of 0, intentionally designed for this case, demonstrates the worst performance (rather than brief as groupBy )

  type Word = String type Sentence = Seq[Word] type Occurrences = scala.collection.Map[Char, Int] def woGrouped(w: Word): Occurrences = { w.groupBy(c => c).map({case (c, list) => (c -> list.length)}) } //> woGrouped: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences def woGetElse0Map(w: Word): Occurrences = { val map = Map[Char, Int]() w.foldLeft(map)((m, c) => m + (c -> (m.getOrElse(c, 0) + 1)) ) } //> woGetElse0Map: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences def woDeflt0Map(w: Word): Occurrences = { val map = Map[Char, Int]().withDefaultValue(0) w.foldLeft(map)((m, c) => m + (c -> (m(c) + 1)) ) } //> woDeflt0Map: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences def dfltHashMap(w: Word): Occurrences = { val map = scala.collection.immutable.HashMap[Char, Int]().withDefaultValue(0) w.foldLeft(map)((m, c) => m + (c -> (m(c) + 1)) ) } //> dfltHashMap: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences def mmDef(w: Word): Occurrences = { val map = scala.collection.mutable.Map[Char, Int]().withDefaultValue(0) w.foldLeft(map)((m, c) => m += (c -> (m(c) + 1)) ) } //> mmDef: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences val functions = List("grp" -> woGrouped _, "mtbl" -> mmDef _, "else" -> woGetElse0Map _ , "dfl0" -> woDeflt0Map _, "hash" -> dfltHashMap _ ) //> functions : List[(String, String => scala.collection.Map[Char,Int])] = Lis //| t((grp,<function1>), (mtbl,<function1>), (else,<function1>), (dfl0,<functio //| n1>), (hash,<function1>)) val len = 100 * 1000 //> len : Int = 100000 def test(len: Int) { val data: String = scala.util.Random.alphanumeric.take(len).toList.mkString val firstResult = functions.head._2(data) def run(f: Word => Occurrences): Int = { val time1 = System.currentTimeMillis() val result= f(data) val time2 = (System.currentTimeMillis() - time1) assert(result.toSet == firstResult.toSet) time2.toInt } def log(results: Seq[Int]) = { ((functions zip results) map {case ((title, _), r) => title + " " + r} mkString " , ") } var groupResults = List.fill(functions.length)(1) val integrals = for (i <- (1 to 10)) yield { val results = functions map (f => (1 to 33).foldLeft(0) ((acc,_) => run(f._2))) println (log (results)) groupResults = (results zip groupResults) map {case (r, gr) => r + gr} log(groupResults).toUpperCase } integrals foreach println } //> test: (len: Int)Unit test(len) test(len * 2) // GRP 14 , mtbl 11 , else 31 , dfl0 36 , hash 34 // GRP 91 , MTBL 111 println("Done") def main(args: Array[String]) { } 

produces

 grp 5 , mtbl 5 , else 13 , dfl0 17 , hash 17 grp 3 , mtbl 6 , else 14 , dfl0 16 , hash 16 grp 3 , mtbl 6 , else 13 , dfl0 17 , hash 15 grp 4 , mtbl 5 , else 13 , dfl0 15 , hash 16 grp 23 , mtbl 6 , else 14 , dfl0 15 , hash 16 grp 5 , mtbl 5 , else 13 , dfl0 16 , hash 17 grp 4 , mtbl 6 , else 13 , dfl0 16 , hash 16 grp 4 , mtbl 6 , else 13 , dfl0 17 , hash 15 grp 3 , mtbl 5 , else 14 , dfl0 16 , hash 16 grp 3 , mtbl 6 , else 14 , dfl0 16 , hash 16 GRP 5 , MTBL 5 , ELSE 13 , DFL0 17 , HASH 17 GRP 8 , MTBL 11 , ELSE 27 , DFL0 33 , HASH 33 GRP 11 , MTBL 17 , ELSE 40 , DFL0 50 , HASH 48 GRP 15 , MTBL 22 , ELSE 53 , DFL0 65 , HASH 64 GRP 38 , MTBL 28 , ELSE 67 , DFL0 80 , HASH 80 GRP 43 , MTBL 33 , ELSE 80 , DFL0 96 , HASH 97 GRP 47 , MTBL 39 , ELSE 93 , DFL0 112 , HASH 113 GRP 51 , MTBL 45 , ELSE 106 , DFL0 129 , HASH 128 GRP 54 , MTBL 50 , ELSE 120 , DFL0 145 , HASH 144 GRP 57 , MTBL 56 , ELSE 134 , DFL0 161 , HASH 160 grp 7 , mtbl 11 , else 28 , dfl0 31 , hash 31 grp 7 , mtbl 10 , else 28 , dfl0 32 , hash 31 grp 7 , mtbl 11 , else 28 , dfl0 31 , hash 32 grp 7 , mtbl 11 , else 28 , dfl0 31 , hash 33 grp 7 , mtbl 11 , else 28 , dfl0 32 , hash 31 grp 8 , mtbl 11 , else 28 , dfl0 31 , hash 33 grp 8 , mtbl 11 , else 29 , dfl0 38 , hash 35 grp 7 , mtbl 11 , else 28 , dfl0 32 , hash 33 grp 8 , mtbl 11 , else 32 , dfl0 35 , hash 41 grp 7 , mtbl 13 , else 28 , dfl0 33 , hash 35 GRP 7 , MTBL 11 , ELSE 28 , DFL0 31 , HASH 31 GRP 14 , MTBL 21 , ELSE 56 , DFL0 63 , HASH 62 GRP 21 , MTBL 32 , ELSE 84 , DFL0 94 , HASH 94 GRP 28 , MTBL 43 , ELSE 112 , DFL0 125 , HASH 127 GRP 35 , MTBL 54 , ELSE 140 , DFL0 157 , HASH 158 GRP 43 , MTBL 65 , ELSE 168 , DFL0 188 , HASH 191 GRP 51 , MTBL 76 , ELSE 197 , DFL0 226 , HASH 226 GRP 58 , MTBL 87 , ELSE 225 , DFL0 258 , HASH 259 GRP 66 , MTBL 98 , ELSE 257 , DFL0 293 , HASH 300 GRP 73 , MTBL 111 , ELSE 285 , DFL0 326 , HASH 335 Done 

Curiously, the most compressed groupBy faster than even a modified map!

+6
Jul 13 '14 at
source share

Starting with Scala 2.13 , method K) (f: A => B) (reduce: (B, B) => B): scala.collection.immutable.Map [K, B] rel = "nofollow noreferrer"> groupMapReduce does this is in one go through the list:

 // val seq = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges") seq.groupMapReduce(identity)(_ => 1)(_ + _) // immutable.Map[String,Int] = Map(banana -> 1, oranges -> 3, apple -> 3) seq.groupMapReduce(identity)(_ => 1)(_ + _)("apple") // Int = 3 

It:

  • elements of the group list (the group part of the MapReduce group )

  • map each occurrence of the grouped value in 1 (part of the map of the Map Reduce group)

  • reduce values ​​in the group of values ​​( _ + _ ) by summing them (reduce the part of groupMap Reduce ).

This is a one-pass version of what can be translated:

 seq.groupBy(identity).mapValues(_.map(_ => 1).reduce(_ + _)) 
+4
Oct 07 '18 at 9:19
source share

Here is another option:

 scala> val list = List(1,2,4,2,4,7,3,2,4) list: List[Int] = List(1, 2, 4, 2, 4, 7, 3, 2, 4) scala> list.groupBy(x => x) map { case (k,v) => k-> v.length } res74: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1, 2 -> 3, 7 -> 1, 3 -> 1, 4 -> 3) 
+3
Apr 21 '15 at 18:57
source share
 scala> val list = List(1,2,4,2,4,7,3,2,4) list: List[Int] = List(1, 2, 4, 2, 4, 7, 3, 2, 4) scala> println(list.filter(_ == 2).size) 3 
+3
Jul 02 '17 at 8:34 on
source share

I did not get the list size using length , but rather size , like the one suggested above, due to the issue reported here .

 val list = List("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges") list.groupBy(x=>x).map(t => (t._1, t._2.size)) 
+3
Nov 17 '17 at 22:22
source share

using cats

 import cats.implicits._ "Alphabet".toLowerCase().map(c => Map(c -> 1)).toList.combineAll "Alphabet".toLowerCase().map(c => Map(c -> 1)).toList.foldMap(identity) 
+2
Aug 07 '18 at 13:44 on
source share

I don't know if there is a proper way to get the size of a list in Scala, but for your situation you can use a sequence.

0
Jan 14 '19 at 0:34
source share



All Articles