I am new to Scala and i am trying to create a function that calculates the amount a certain object appears in a sequence. So in this case we have a sequence with 1 Hippo and 3 Tigers in it. I want the amount of Tigers in the sequence. So the outcome of the function amountOfTigers should be an integer: 3. I want to make use of pattern matching and recursion to solve this. But i dont really know how to do this.
sealed trait Animal
case class Hippo(name: String, age: Int) extends Animal
case class Tiger(name: String, age: Int) extends Animal
def amountOfTigers(animals: Seq[Animal]): Int = animals match {
case head : tail => if (head.isInstanceOf[Tiger]) println(head); amountOfTigers(tail)
}
val data = Seq[Animal](
Hippo("Mino", 4),
Tiger("Justin", 1),
Tiger("Jason", 20),
Tiger("Sloop", 10)
)
amountOfTigers(data)
println is used for testing purposes. The output i am getting right now is: Tiger(Justin,1) Tiger(Jason,20) Tiger(Sloop,10)
I want as a result the amount of Tigers in a sequence. So in this case its 3.
CodePudding user response:
If you want to avoid recursion (which I personally suggest in this case - cause it's just an ordinary array of data), I suggest you use a loop, this way:
def amountOfTigers(animals: Seq[Animal]): Int = animals.count(_.isInstanceOf[Tiger])
If you insist using recursion, I suggest using @tailrec
as Christian hinted:
def amountOfTigersRec(animals: Seq[Animal]): Int = {
@tailrec
def rec_fun(tail: Seq[Animal], count: Int): Int = tail match {
case Tiger(_, _) : tail => rec_fun(tail, count 1)
case _ : tail => rec_fun(tail, count)
case Nil => count
}
rec_fun(animals, 0)
}
CodePudding user response:
This is an example:
sealed trait Animal
case class Hippo(name: String, age: Int) extends Animal
case class Tiger(name: String, age: Int) extends Animal
def amountOfTigers(animals: Seq[Animal]): Int = animals match {
case Seq() => 0
case Tiger(_, _) : tail => amountOfTigers(tail) 1
case head : tail => amountOfTigers(tail)
}
val data = Seq[Animal](
Hippo("Mino", 4),
Tiger("Justin", 1),
Tiger("Jason", 20),
Tiger("Sloop", 10)
)
print(amountOfTigers(data))
Things you might want to check out:
- How to pattern match in Scala: https://docs.scala-lang.org/tour/pattern-matching.html as you rarely use isInstanceOf in Scala
- For recursive functions, usually you start with thinking about the trivial case. Here: An empty seq has zero tigers.
- Note that this example isn't very efficient, as it isn't tail recursive. Tail recursion is optimized into a loop by the Scala compiler. See e.g. https://www.geeksforgeeks.org/tail-recursion-in-scala/ for more details about this.