So I have a list of 0's and 1's, I want to find the count of each element and output this to a list. I can think of a recursive way to do it with functions but is there any helper functions which can help to convert this?
I believe groupBy could be useful but it seems to group all the elements into one partition or another, not into the way I want.
I want to have a list of the count of numbers until each transition from 0 to 1 and 1 to 0. ie, if we have 0,0,0, .. ok we counted 3 zeros so remember 3, then we have 1,1,1,1 so we counted 4 1's, so we remember 4, so far we have a list of [3,4...] and so on
tail-rec version of Yann Moisan's solution:
def pack[A](ls: Seq[A], prev: Seq[Int] = Seq.empty): Seq[Int] = {
if (ls.isEmpty) prev
else {
val (packed, next) = ls span {_ == ls.head }
pack(next, prev :+ packed.size)
}
}
def pack[A](ls: List[A]): List[Int] = {
if (ls.isEmpty) List(0)
else {
val (packed, next) = ls span { _ == ls.head }
if (next == Nil) List(packed.size)
else packed.size :: pack(next)
}
}
This might be a little complicated. but I'd go with it.
scala> implicit class ListHelper[A](ls:List[A]) {
def partitionBy(f: (A, A) => Boolean) = if (ls.isEmpty) List.empty[Int]
else (ls zip (ls.head :: ls)).foldLeft(List.empty[Int]){
case (Nil, _) => List(1)
case (x :: xs, (a, b)) => if (a == b) (x + 1) :: xs else 1 :: x :: xs
}.reverse
}
defined class ListHelper
scala> List(0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1).partitionBy(_ == _)
res27: List[Int] = List(3, 4, 2, 2)
This is based on the clojure function partition-by
This is groupBy.
val tuple = list.foldRight((0,0)) { (x, accum) =>
if (x == 0) (accum._1 +1, accum._2) else (accum._1, accum._2 +1)
}
List(tuple._1, tuple._2)
on similar lines here is fliptracker (for non-empty lists):
def fliptracker(list: List[Int]) = {
val initial = (list.head, 0, List.empty[Int])
val result = list.foldLeft(initial) {
(acc, x) =>
if (acc._1 == x) (acc._1, acc._2 + 1, acc._3)
else (x, 1, acc._3 ::: List(acc._2))
}
result._3 ::: List (result._2)
}
fliptracker(List(0,0,0,1,1,1,1,0,0,1,1)) // List(3, 4, 2, 2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With