How can I convert
List(1, 2, "3")
to
List(1, 2, 3)
since List(1, 2, "3") is of type List[Any] and I can't use .toInt on Any.
That should be sufficient solution:
l.map(_.toString.toInt)
Starting Scala 2.13 and the introduction of String#toIntOption, we can make #liosedhel's answer a bit safer if needs be:
// val l: List[Any] = List(1, 2, "3")
l.flatMap(_.toString.toIntOption)
// List[Int] = List(1, 2, 3)
Related
Can you please explain what init method performs with respect to below list
i can see the result of new list says that last sequence is being omitted from the existing list.
val numbers = List(1, 2, 3, 4, 5)
val result = numbers.init
println(result)
.init and .last are the compliments to the .head and .tail methods.
val nums = List(1,2,3,4)
nums.head //res0: Int = 1
nums.tail //res1: List[Int] = List(2, 3, 4)
nums.init //res2: List[Int] = List(1, 2, 3)
nums.last //res3: Int = 4
def init: List[A] which selects all elements except the last.
l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)
scala> l.last
res58: Int = 8
scala> l.init
res59: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> val testList = List(1,2,3,4,5)
testList: List[Int] = List(1, 2, 3, 4, 5)
scala> testList.init
res0: List[Int] = List(1, 2, 3, 4)
scala> testList.last
res1: Int = 5
scala> testList.head
res2: Int = 1
scala> testList.tail
res3: List[Int] = List(2, 3, 4, 5)
Can someone tell me why I am getting different results when using Tuple2[List,List] and List[List] as my Product in the code below? Specifically I would like to know why the second value of the list of lists gets wrapped in another list?
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)
scala> val c = List(a,b)
c: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6))
scala> c.productIterator.foreach( println(_) )
List(1, 2, 3)
List(List(4, 5, 6)) // <-- Note this
scala> val d = (a,b)
d: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5, 6))
scala> d.productIterator.foreach( println(_) )
List(1, 2, 3)
List(4, 5, 6) // <-- Compared to this
(I have read the (absolutely minimal) description of Scala's Product and the productIterator method on http://www.scala-lang.org/api/current/index.html#scala.Product )
Basically, Tuple means a product between all of its elements, but a non-empty List is a product between its head and tail.
This happens for List, because all case classes extend Product, and represent a product between all their elements similar to tuples. And non-empty List is defined as a case class, containing head and tail: final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B], which inherits the default implementation of Product by case class.
You can observe more of this behaviour with other Lists with 1 or more than 2 elements:
scala> List(a).productIterator.foreach(println)
List(1, 2, 3)
List()
scala> List(a, a).productIterator.foreach(println)
List(1, 2, 3)
List(List(1, 2, 3))
scala> List(a, a, a).productIterator.foreach(println)
List(1, 2, 3)
List(List(1, 2, 3), List(1, 2, 3))
Working with Lists in Scala I would like a simple way to get all elements but the last element. Is there a complementary method for .last similar to .head/.tail complement?
I'd rather not dirty up code with something like:
val x: List[String] = List("abc", "def", "ghi")
val allButLast: List[String] = x.reverse.tail.reverse
// List(abc, def)
Thanks.
init selects all elements but the last one.
List API for init.
scala> List(1,2,3,4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)
scala> res0.init
res1: List[Int] = List(1, 2, 3, 4)
The 4 related methods here are head, tail, init, and last.
head and last get the first and final member, whereas
tail and init exclude the first and final members.
scala> val list = (0 to 10).toList
list: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list.head
res0: Int = 0
scala> list.tail
res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list.init
res2: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> list.last
res3: Int = 10
You should also take care, because all 4 of them are unsafe on the empty list and will throw exceptions.
These methods are defined on GenTraversableLike, which List implements.
That's init.
link to Scaladoc: http://www.scala-lang.org/api/2.11.5/index.html#scala.collection.immutable.List#init:Repr
def init: List[A]
Selects all elements except the last.
Also, note that it's defined in GenTraversableLike, so pretty much any Scala collection has this method.
For dropping off any number of items from the end of a list consider dropRight,
val xs = (1 to 5).toList
xs.dropRight(1)
List(1, 2, 3, 4)
xs.dropRight(2)
List(1, 2, 3)
xs.dropRight(10)
List()
scala> List(1,2,3,4,5,6,7).takeWhile(i=>i<5)
res1: List[Int] = List(1, 2, 3, 4)
What if I also need to include 5 in the result?
Assuming that the function that you will be using is more complicated than the taking first 5 elements then,
You can do
scala> List(1,2,3,4,5,6,7)
res5: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> res5.takeWhile(_<5) ++ res5.dropWhile(_<5).take(1)
res7: List[Int] = List(1, 2, 3, 4, 5)
Also
scala> res5.span(_<5)
res8: (List[Int], List[Int]) = (List(1, 2, 3, 4),List(5, 6, 7))
scala> res8._1 ++ res8._2.take(1)
res10: List[Int] = List(1, 2, 3, 4, 5)
Also
scala> res5.take(res5.segmentLength(_<5, 0) + 1)
res17: List[Int] = List(1, 2, 3, 4, 5)
scala> res5.take(res5.indexWhere(_>5))
res18: List[Int] = List(1, 2, 3, 4, 5)
Edit
If this is not a parallelized computation and you won't be using the parallel collections:
var last = myList.head
val rem = myList.takeWhile{ x=>
last = x
x < 5
}
last :: rem
anonymous function forming a closure around the solution you want.
Previous Answer
I'd settle for the far less complicated:
.takeWhile(_ <= 5)
wherein you're just using the less than or equal operator.
List(1,2,3,4,5,6,7,8).takeWhile(_ <= 5)
This is best optimal solution for it
scala> Array(1, 2, 3).toString
res1: String = [I#11cf437c
scala> List(1, 2, 3).toString
res2: String = List(1, 2, 3)
scala> Vector(1, 2, 3).toString
res3: String = Vector(1, 2, 3)
Logically, one would expect Array(1, 2, 3).toString to return "Array(1, 2, 3)".
Update: seems to me like Array maps to the built in Java array type—is this correct? and if yes, is this the reason Array.toString has to behave like this?
It is because Array is a Java object. You can however use runtime.ScalaRunTime.stringOf if it suits your needs.
scala> runtime.ScalaRunTime.stringOf(Array(1, 2, 3))
res3: String = Array(1, 2, 3)
scala> List(1,2,3).getClass()
res0: Class[_ <: List[Int]] = class scala.collection.immutable.$colon$colon
scala> Vector(1,2,3).getClass()
res1: Class[_ <: scala.collection.immutable.Vector[Int]] = class scala.collection.immutable.Vector
scala> Array(1,2,3).getClass()
res2: Class[_ <: Array[Int]] = class [I
List and Vector are Scala classes, so they have a nice representation. Array comes from Java and practices Java's ugliness.