Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safely Get Tail of Array

Tags:

scala

I called tail on an Array, but saw a warning.

scala> val arr = Array(1,2)
arr: Array[Int] = Array(1, 2)

scala> arr tail
warning: there were 1 feature warning(s); re-run with -feature for details
res3: Array[Int] = Array(2)

Scaladocs for Array shows an UnsupportedOperationException [will be thrown] if the mutable indexed sequence is empty.

Is there a safe, won't throw exception, way to get the tail of an array?

like image 719
Kevin Meredith Avatar asked Sep 06 '13 00:09

Kevin Meredith


2 Answers

Is there a safe, won't throw exception, way to get the tail of an array?

You can use drop:

scala> Array(1, 2, 3).drop(1)
res0: Array[Int] = Array(2, 3)

scala> Array[Int]().drop(1)
res1: Array[Int] = Array()

Also note that as mentioned by @TravisBrown in the comment below, drop doesn't differentiate between an empty tail (for collections with one element) and the absence of tail (for empty collections) since in both the cases, drop(1) would return an empty collection.

like image 157
Marimuthu Madasamy Avatar answered Sep 30 '22 11:09

Marimuthu Madasamy


First of all, the warning doesn't have anything to do with the fact that you're using an unsafe method. If you restart the REPL with -feature you'll see the following:

scala> arr tail
<console>:9: warning: postfix operator tail should be enabled
by making the implicit value language.postfixOps visible...

And a pointer to the documentation for scala.language.postfixOps, which includes the following note:

Postfix operators interact poorly with semicolon inference. Most programmers avoid them for this reason.

This is good advice. Being able to write arr tail instead of arr.tail isn't worth the fuss.

Now about the safety issue. The standard library doesn't provide a tailOption for collections, but you can get the same effect using headOption and map:

scala> val arr = Array(1, 2)
arr: Array[Int] = Array(1, 2)

scala> arr.headOption.map(_ => arr.tail)
res0: Option[Array[Int]] = Some([I@359be9fb)

If this is too verbose or opaque or inefficient for you, you can easily create an implicit class that would add a nicer tailOption to Array (or Seq, or IndexedSeq, etc.).

like image 26
Travis Brown Avatar answered Sep 30 '22 13:09

Travis Brown