I am trying to find the last element of a list in Scala using pattern matching. I tried following code
def last[A](list: List[A]):A = list match {
case head :: Nil => head
case head :: tail => last(tail)
case _ => Nil
}
The last case i.e. case _ => Nil
is throwing error as type mismatch (found Nil.type require A)
I know this problem can be solved using other methods but using only pattern matching is there a way to solve this?
As the list is of generic type so I cannot replace Nil
with default value of type A which can only be determined at runtime.
Removing this line: case _ => Nil
is obviously working but with a warning that it will fail in case of Nil argument.
So, how can I handle Nil argument in this scenario?
You can pattern match with :+
.
def last[A](list: List[A]) = list match {
case init :+ last => Some(last)
case _ => None
}
As you are not sure whether your list does contain any object you should handle such situation in general way. I'd suggest returning option type in your last
method as follows:
def last[A](list: List[A]): Option[A] = list match {
case head :: Nil => Some(head)
case head :: tail => last(tail)
case _ => None
}
Then in your code you can use monad-like interface to work with the result. You can either use map
and process data in provided function, or use get
method on option in case you are absolutely sure the list was not empty.
use Option[T]
to return the result, so if there is some element return Some(lastElement)
otherwise Option.empty
Example,
def last[A](list: List[A]): Option[A] = list match {
case head :: Nil => Option(head)
case head :: tail => last(tail)
case _ => Option.empty
}
it("returns last element") {
assert(last(List("apple")) == Some("apple"))
assert(last(List("apple", "mango")) == Some("mango"))
assert(last(List()) == Option.empty)
assert(last(List()) == None)
}
How to access the Option[T]
?
last(List("In absentia", "deadwind")) match {
case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}") //prints Yayy there was lastValue = deadwind
case None => println("Oops list was empty")
}
last(List()) match {
case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}")
case None => println("Oops list was empty") //prints Oops list was empty
}
// or using map
last(List("In absentia", "deadwind")).map(lastValue => print(s"lastValue is ${lastValue}"))
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