dondog
dondog

Reputation: 399

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?

Upvotes: 37

Views: 53338

Answers (6)

nondeterministic
nondeterministic

Reputation: 521

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)

Upvotes: 0

Marton Tatai
Marton Tatai

Reputation: 190

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.

Upvotes: 1

smellerbee
smellerbee

Reputation: 1883

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.

  1. Using built in function last might not be an option in interview questions.
  2. Reversing and head takes additional operations, which the interviewer might ask to reduce.
  3. 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

Upvotes: 0

michael.kebe
michael.kebe

Reputation: 11085

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.

Upvotes: 91

Jus12
Jus12

Reputation: 18024

Another version without using last (for whatever reason you might need it).

def last(L:List[Int]) = L(L.size-1)

Upvotes: 12

Pere Villega
Pere Villega

Reputation: 16439

You should better do:

 val a = List(1,2,3) //your list
 val last = a.reverse.head

Cleaner and less error-prone :)

Upvotes: 9

Related Questions