Home > Mobile >  count number of groups of certain element
count number of groups of certain element

Time:11-02

I have a list, I need to count the number of groups of certain elements(1 or 0).

(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1)

val count1Grp = daysSequence.foldLeft(List[Int]()){(acc, elem) =>
  if(acc.isEmpty) elem :: acc else if(acc.head == elem) acc else elem :: acc
}
.count(_ == 1)

val count0Grp = daysSequence.foldLeft(List[Int]()){(acc, elem) =>
  if(acc.isEmpty) elem :: acc else if(acc.head == elem) acc else elem :: acc
}
.count(_ == 0)

I fold similar neighbour elements and then do a count of what is left. And get

count1Grp = 1
count0Grp = 1

Another example. Both rows same result.

(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
(-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
count1Grp = 1
count0Grp = 2

But how should I do it if I needed 2 or more similar elements together to quantify as a group? In the first case 0 wouldn't fit the criteria and should result in

count1Grp = 1
count0Grp = 0

CodePudding user response:

Why not get a Map with a count of every group in the collection? Then only one traversal is needed.

def groupCount[A](xs      : Seq[A]
                 ,grpSize : Int = 1
                 ,acc     : Map[A,Int] = Map[A,Int]()
                 ): Map[A,Int] = xs match {
  case Seq() => acc
  case hd  : _ =>
    val (grp,rest) = xs.span(_ == hd)
    if (grp.size < grpSize)
      groupCount(rest, grpSize, acc)
    else
      groupCount(rest, grpSize, acc   (hd -> (acc.getOrElse(hd,0) 1)))
}

Here's a Scastie session with a few usage examples.

  • Related