# Find all subsequences in the sequence

### Nikita Zonov ・2 min read

Let's start with the signature of our function

```
def groupSubseq[T](in: Seq[T])(p: (T, T) => Boolean): Seq[Seq[T]]
```

Here **p** is predicate we use before add item to the existing subseq or create new one

We are going to use foldLeft

```
def groupSubseq[T](in: Seq[T])(p: (T, T) => Boolean): Seq[Seq[T]] = in
.foldLeft(Seq.empty[Seq[T]])((seq, item) => seq match {
case Nil => Seq(Seq(item)) // processing first element
case currentSeq +: tail =>
if (p(currentSeq.head, item)) {
// new element satisfies the condition, add it to the subsequence
(item +: currentSeq) +: tail
} else {
// new element not satisfies the condition, start new subsequence
Seq(item) +: seq
}
})
```

Looks like we've done here. But let me explain ))... This post is a result of a few similar tasks I've faced recently.

**Task 1**

*Find all the sequences of the same character in the given string and count number of the character in each sequence*

```
def countChar(seq: String): Seq[Char, Int] = ???
val test1 = "aaabbaaaabbb"
countChar(test1)
//res0: List((a,3), (b,2), (a,4), (b,3))
```

**Task 2**

*Count number of all the sequences of the same sign in the given sequence of Int*

```
def countSign(seq: Set[Int]): Int = ???
val test1 = Seq(1, 2, 3, -3, -2, 6, 7, 8, 9, -3, -1, -6, 7)
countSign(test1)
//res0: 3
```

Using our recent invention we may solve it easily

```
def countChar(seq: String) =
groupSubseq(seq)(_ == _).map(seq => seq.head -> seq.length).reverse
countChar("aaabbaaacddddd")
// res0: Seq[(Char, Int)] = List((a,3), (b,2), (a,3), (c,1), (d,5))
def countSign(seq: Seq[Int]) = groupSubseq(seq)(_ * _ > 0).count(_.length > 2)
countSign(Seq(1, 2, 3, 4, -1, 1, -1, -2, -3, -4, 0, 0, 0))
// res1: Int = 2
```

I hope to see your pros and cons in the comments. Thanks for reading.