'Choosing the last element of a list
scala> last(List(1, 1, 2, 3, 5, 8))
res0: Int = 8
for having a result above, I wrote this code:
val yum = args(0).toInt
val thrill:
def last(a: List[Int]): List[Int] = {
println(last(List(args(0).toInt).last)
}
What is the problem with this code?
Solution 1:[1]
You can use last, which returns the last element or throws a NoSuchElementException, if the list is empty.
scala> List(1, 2, 3).last
res0: Int = 3
If you do not know if the list is empty or not, you may consider using lastOption, which returns an Option.
scala> List().lastOption
res1: Option[Nothing] = None
scala> List(1, 2, 3).lastOption
res2: Option[Int] = Some(3)
Your question is about List, but using last on a infinite collection (e.g. Stream.from(0)) can be dangerous and may result in an infinite loop.
Solution 2:[2]
Another version without using last (for whatever reason you might need it).
def last(L:List[Int]) = L(L.size-1)
Solution 3:[3]
You should better do:
val a = List(1,2,3) //your list
val last = a.reverse.head
Cleaner and less error-prone :)
Solution 4:[4]
Albiet this is a very old question, it might come handy that the performance impact of head and last operations seems to be laid out here http://docs.scala-lang.org/overviews/collections/performance-characteristics.html.
Solution 5:[5]
The recursive function last should following 2 properties. Your last function doesn't have any of them.
Requirement #1. An exit condition that does not call recursive function further.
Requirement #2. A recursive call that reduces the elements that we began with.
Here are the problems I see with other solutions.
- Using built in function last might not be an option in interview questions.
- Reversing and head takes additional operations, which the interviewer might ask to reduce.
- What if this is a custom linked list without the size member?
I will change it to as below.
def last(a: List[Int]): Int = a match {
//The below condition defines an end condition where further recursive calls will not be made. requirement #1
case x::Nil => x
//The below condition reduces the data - requirement#2 for a recursive function.
case x:: xs => last(xs)
}
last(List(1,2,3))
Result
res0: Int = 3
Solution 6:[6]
In these types of questions the useful take and takeRight are often overlooked. Similar to last, one avoids the slow initial reversing of a list, but unlike last, can take the last (or first) n items as opposed to just a single one:
scala> val myList = List(1,2,3)
myList: List[Int] = List(1, 2, 3)
scala> myList.takeRight(2)
res0: List[Int] = List(2, 3)
scala> myList.takeRight(1)
res1: List[Int] = List(3)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Jus12 |
| Solution 3 | Pere Villega |
| Solution 4 | Marton Tatai |
| Solution 5 | Ravi |
| Solution 6 | nondeterministic |
