Choosing the last element of a list - 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?

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.

Another version without using last (for whatever reason you might need it).
def last(L:List[Int]) = L(L.size-1)

You should better do:
val a = List(1,2,3) //your list
val last = a.reverse.head
Cleaner and less error-prone :)

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.

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

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)

Related

Pattern match against List 'init' and 'last' instead of 'head' and 'tail'

I know that it's possible to easily pattern match against the head (or an arbitrary number of initial elements) and tail of a List:
val items = List(1, 2, 3, 4)
val first :: rest = items
println(first, rest) // 1, List(2, 3, 4)
However, I would like to do it the other way - can you use a pattern to get the init and last of the list?
val items = List(1, 2, 3, 4)
val rest ??? last = items
println(rest, last) // List(1, 2, 3), 4
In JavaScript this would look like:
const [...init, last] = items
You can use the :+ custom extractor object.
So the code would look like this:
val rest :+ last = items
However, note that this is equally inefficient than doing:
val last :: rest = items.reverse
But, if you then need to decompose rest again, then reversing it first will be more efficient.
Finally, remember both are unsafe since they will throw in case the List is empty.
This should work:
val xs :+ x = items
Check out: https://www.scala-lang.org/files/archive/api/2.12.0/scala/collection/Seq.html#:+(elem:A):Seq[A]

Scala Lists of lists of integers

I am new to Scala and am a bit confused.
Given a list of lists List[List[Int]], how can one call a specific index of an element of each list, for example the second element of each list?
Simple:
val ints = List( List(1,2), List(3,4) )
val result = ints.map( l => l(1) )
This will produce (2,4).
While both of the other answers work, here is another version that is both safe to use and not complex. You can lift a Seq to a Function[Int, Option[A]] to make apply return Options instead of throwing exceptions. In Addition you can use flatMap instead of map{...}.flatten
List(List(1), List(1,2), List(1,2,3)).flatMap { xs =>
xs.lift(1)
}
// res1: List[Int] = List(2, 2)

How to replace a given item in a list?

This describes the problem pretty well:
scala> var l2 = List(1,2,3)
l2: List[Int] = List(1, 2, 3)
scala> l2(2) = 55
<console>:10: error: value update is not a member of List[Int]
l2(2) = 55
^
scala.List is immutable, meaning you cannot update it in place. If you want to create a copy of your List which contains the updated mapping, you can do the following:
val updated = l2.updated( 2, 55 )
There are mutable ordered sequence types as well, in scala.collection.mutable, such as Buffer types which seem more like what you want. If you try the following you should have more success:
scala> import scala.collection._
import scala.collection._
scala> val b = mutable.Buffer(1,2,3)
b: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2, 3)
scala> b(2) = 55
scala> b
res1: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2, 55)
Edit: Just to note that some other answers have mentioned that you should use a "mutable List type" - this is true, but "List" in Scala just refers to the single-linked list, whereas in Java it's generally used for any ordered, random-access collection. There is also a DoubleLinkedList, which is more like a Java LinkedList, and a MutableList, which is a type used for the internals of some other types.
Generally speaking what you probably want in Scala is a Buffer for this job; especially since the default implementation is an ArrayBuffer, which is pretty close to being the same as ArrayList, most peoples' default, in Java.
If you ever want to find out what the closest "mapping" of a Java collections interface to the Scala world is, though, the easiest thing to do is probably just check what JavaConversions does. In this case you can see the mapping is to Buffer:
scala.collection.mutable.Buffer <=> java.util.List
The List you are creating is immutable.
scala> val l = List(1,2,3)
l: List[Int] = List(1, 2, 3)
scala> l.getClass
res3: java.lang.Class[_] = class scala.collection.immutable.$colon$colon
Use a mutable List instead and you should be fine.
But you can wrap the assignment in an implicit if you don't like updated
implicit class RichList[A](l: List[A]) {
def update(which: Int, what: A): List[A] = {
l.updated(which, what)
}
}
val l = List(1, 2, 3)
val l2 = l(2) = 55
List(1, 2, 55)
Your problem is that Lists in scala are immutable, you need to use a mutable list instead.
Import scala.collection.mutable.Queue and use that instead. Queue is a MutableList, so it should do what you want.
Lists are immutable in scala. But if you want to replace an element in a List you can use "updated" method like this
val num:List[Int]=List(1,5,4,7,8,2,10)
num=num.updated(0,22)
Since Lists are immutable,this creates a copy of the first List called num(as we assigned the new list to 'num') by replacing 0th element to 22.So the genaral updated method is
listname.updated(index,value)

Creating lists and sets in Scala: What do I actually get?

If I create a Set in Scala using Set(1, 2, 3) I get an immutable.Set.
scala> val s = Set(1, 2, 3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
Q1: What kind of Set is this actually? Is it some hash-set? What is the complexity of look-ups for instance?
Q2: Where can I read up on this "set-creating" method? I thought that it was the apply method but the docs says "This method allows sets to be interpreted as predicates. It returns true, iff this set contains element elem."
Similarly, if I create a List using List(1, 2, 3), I get
scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> l.getClass
res13: java.lang.Class[_] = class scala.$colon$colon
Q3: Again, what do I get? In this case I can't even immediately tell if it's mutable or not, since it's not even part of the scala.collection-package. Why does this live in the scala package?
Q4: Where in the API can I read about this "list-creating" method?
Q1: In this specific case you get a Set3 which is an immutable set of exactly three arguments. Presumably it uses if-else if-else to check inclusion. If you create a set of more than 4 elements, you get an immutable hash set.
Q2: You need to look at the apply method of the object Set, not the class. The apply method of the Set class is what is called when you do someSet(something).
Q3: scala.:: is a non-empty immutable singly linked list (if you do List() without arguments, you get Nil which is an immutable empty list). It lives in the scala package because it is considered so basic that it belongs in the base package.
Q4: See Q2.
Just to add to sepp2k's excellent answer to Q3, where he says
It lives in the scala package because
it is considered so basic that it
belongs in the base package.
This applies to Scala 2.7
In Scala 2.8, the collections classes have been reorganized, and now the :: class lives in scala.collection.immutable, and the name scala.:: is a type alias for scala.collection.immutable.::.
Welcome to Scala version 2.8.0.RC5 (OpenJDK 64-Bit Server VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> l.getClass
res0: java.lang.Class[_] = class scala.collection.immutable.$colon$colon
scala> scala.::
res1: collection.immutable.::.type = scala.collection.immutable.$colon$colon$#6ce5d622
if you call getClass method on the
scala> val list = List(1,2,3,45)
list: List[Int] = List(1, 2, 3, 45)
scala> val seq = Seq(1,2,3,4,5)
seq: Seq[Int] = List(1, 2, 3, 4, 5)
scala> list.getClass
res13: Class[_ <: List[Int]] = class scala.collection.immutable.$colon$colon
scala> seq.getClass
res14: Class[_ <: Seq[Int]] = class scala.collection.immutable.$colon$colon
That’s because scala.collection.immutable.List is an abstract class, and it comes with two implementations: the scala.Nil class and scala.::. In Scala, :: is a valid identifier, and you could use it to name a class. Nil represents an empty list, and scala.:: represents any nonempty list.

scala - Getting a read-only sublist view of a List

I would like a List, Seq, or even an Iterable that is a read-only view of a part of a List, in my specific case, the view will always start at the first element.
List.slice, is O(n) as is filter. Is there anyway of doing better than this - I don't need any operations like +, - etc. Just apply, map, flatMap, etc to provide for list comprehension syntax on the sub list.
Is the answer to write my own class whose iterators keep a count to know where the end is?
How about Stream? Stream is Scala's way to laziness. Because of Stream's laziness, Stream.take(), which is what you need in this case, is O(1). The only caveat is that if you want to get back a List after doing a list comprehension on a Stream, you need to convert it back to a List. List.projection gets you a Stream which has most of the opeations of a List.
scala> val l = List(1, 2, 3, 4, 5)
l: List[Int] = List(1, 2, 3, 4, 5)
scala> val s = l.projection.take(3)
s: Stream[Int] = Stream(1, ?)
scala> s.map(_ * 2).toList
res0: List[Int] = List(2, 4, 6)
scala> (for (i <- s) yield i * 2).toList
res1: List[Int] = List(2, 4, 6)
List.slice and List.filter both return Lists -- which are by definition immutable.The + and - methods return a different List, they do not change the original List. Also, it is hard to do better than O(N). A List is not random access, it is a linked list. So imagine if the sublist that you want is the last element of the List. The only way to access that element is to iterate over the entire List.
Well, you can't get better than O(n) for drop on a List. As for the rest:
def constantSlice[T](l: List[T], start: Int, end: Int): Iterator[T] =
l.drop(start).elements.take(end - start)
Both elements and take (on Iterator) are O(1).
Of course, an Iterator is not an Iterable, as it is not reusable. On Scala 2.8 a preference is given to returning Iterable instead of Iterator. If you need reuse on Scala 2.7, then Stream is probably the way to go.