Scala syntax problem - scala

The following code can be compiled
def isEven(a:Int)=
if (a%2==0) true else false
def main(args: Array[String]) {
List(1, 10) filter isEven foreach println
but if I change to following ( List(1,10) --> List(1 to 10))
def isEven(a:Int)=
if (a%2==0) true else false
def main(args: Array[String]) {
List(1 to 10) filter isEven foreach println
}
What's difference between List(1,10) and List(1 to 10) ?

List(1, 2) is simply a list with two Int elements: 1 and 2. The expression 1 to 10 creates a Range instance, so List(1 to 10) is a list with one element: a Range.

List(1, 10) is a List[Int] whereas List(1 to 10) is a List[Range]. Observe the types in the following REPL session:
scala> 1 to 10
res3: scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne = Range(1, 2, 3, 4, 5, 6, 7
, 8, 9, 10)
scala> List(1 to 10)
res4: List[scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne] = List(Range(1, 2, 3,
4, 5, 6, 7, 8, 9, 10))
scala> List(1, 10)
res5: List[Int] = List(1, 10)

missingfaktor is right, so this is just an addition.
If you want a List[Int] with numbers from 1 to 10, you can write
List(1 to 10:_*)
or
1 to 10 toList

Related

Scala .init method example

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)

Removing an element from MutableList in Scala

I have a MutableList and I want to remove an element from it but I cannot find the appropriate method. There is a method to remove element from ListBuffer like this:
val x = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
x -= 5
I am unable to find an equivalent method on MutableList.
MutableList lacks -= and --= because it does not extend the Shrinkable trait. Various motivations for this can be found here.
MutableList does have diff, filter, and other methods which can help you in case you are in a situation where reassigning a variable (or instantiating a new variable) might be an option, and performance concerns aren't paramount:
var mylist = MutableList(1, 2, 3)
mylist = mylist diff Seq(1)
val myNewList = mylist.filter(_ != 2)
val indexFiltered = mylist.zipWithIndex.collect { case (el, ind) if ind != 1 => el }
You can often use ListBuffer instead of MutableList, which will unlock the desired -= and --= methods:
val mylist = ListBuffer(1, 2, 3)
mylist -= 1 //mylist is now ListBuffer(2, 3)
mylist --= Seq(2, 3) //mylist is now empty
It's not the answer, just to warn you about problems (at least in 2.11.x):
//street magic
scala> val a = mutable.MutableList(1,2,3)
a: scala.collection.mutable.MutableList[Int] = MutableList(1, 2, 3)
scala> a += 4
res7: a.type = MutableList(1, 2, 3, 4)
scala> a
res8: scala.collection.mutable.MutableList[Int] = MutableList(1, 2, 3, 4)
scala> a ++= List(8,9,10)
res9: a.type = MutableList(1, 2, 3, 4, 8, 9, 10)
scala> val b = a.tail
b: scala.collection.mutable.MutableList[Int] = MutableList(2, 3, 4, 8, 9, 10)
scala> b.length
res10: Int = 6
scala> a.length
res11: Int = 7
scala> a ++= List(8,9,10)
res12: a.type = MutableList(1, 2, 3, 4, 8, 9, 10, 8, 9, 10)
scala> b += 7
res13: b.type = MutableList(2, 3, 4, 8, 9, 10, 7)
scala> a
res14: scala.collection.mutable.MutableList[Int] = MutableList(1, 2, 3, 4, 8, 9, 10, 7)
scala> b
res15: scala.collection.mutable.MutableList[Int] = MutableList(2, 3, 4, 8, 9, 10, 7)
scala> a ++= List(8,9,10)
res16: a.type = MutableList(1, 2, 3, 4, 8, 9, 10, 7)
This example is taken from some gist - I've posted it on facebook with #devid_blein #street_magic tags, but can't find original link on the internet.

takeWhile: also need first element failed the condition in scala

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

How can I sort List[Int] objects?

What I want to do is sort List objects in Scala, not sort the elements in the list. For example If I have two lists of Ints:
val l1 = List(1, 2, 3, 7)
val l2 = List(1, 2, 3, 4, 10)
I want to be able to put them in order where l1 > l2.
I have created a case class that does what I need it to but the problem is that when I use it none of my other methods work. Do I need to implement all the other methods in the class i.e. flatten, sortWith etc.?
My class code looks like this:
class ItemSet(itemSet: List[Int]) extends Ordered[ItemSet] {
val iSet: List[Int] = itemSet
def compare(that: ItemSet) = {
val thisSize = this.iSet.size
val thatSize = that.iSet.size
val hint = List(thisSize, thatSize).min
var result = 0
var loop = 0
val ths = this.iSet.toArray
val tht = that.iSet.toArray
while (loop < hint && result == 0) {
result = ths(loop).compare(tht(loop))
loop += 1
}
if (loop == hint && result == 0 && thisSize != thatSize) {
thisSize.compare(thatSize)
} else
result
}
}
Now if I create an Array of ItemSets I can sort it:
val is1 = new ItemSet(List(1, 2, 5, 8))
val is2 = new ItemSet(List(1, 2, 5, 6))
val is3 = new ItemSet(List(1, 2, 3, 7, 10))
Array(is1, is2, is3).sorted.foreach(i => println(i.iSet))
scala> List(1, 2, 3, 7, 10)
List(1, 2, 5, 6)
List(1, 2, 5, 8)
The two methods that are giving me problems are:
def itemFrequencies(transDB: Array[ItemSet]): Map[Int, Int] = transDB.flatten.groupBy(x => x).mapValues(_.size)
The error I get is:
Expression of type Map[Nothing, Int] doesn't conform to expected type Map[Int, Int]
And for this one:
def sortListAscFreq(transDB: Array[ItemSet], itemFreq: Map[Int, Int]): Array[List[Int]] = {
for (l <- transDB) yield
l.sortWith(itemFreq(_) < itemFreq(_))
}
I get:
Cannot resolve symbol sortWith.
Is there a way I can just extend List[Int] so that I can sort a collection of lists without loosing the functionality of other methods?
The standard library provides a lexicographic ordering for collections of ordered things. You can put it into scope and you're done:
scala> import scala.math.Ordering.Implicits._
import scala.math.Ordering.Implicits._
scala> val is1 = List(1, 2, 5, 8)
is1: List[Int] = List(1, 2, 5, 8)
scala> val is2 = List(1, 2, 5, 6)
is2: List[Int] = List(1, 2, 5, 6)
scala> val is3 = List(1, 2, 3, 7, 10)
is3: List[Int] = List(1, 2, 3, 7, 10)
scala> Array(is1, is2, is3).sorted foreach println
List(1, 2, 3, 7, 10)
List(1, 2, 5, 6)
List(1, 2, 5, 8)
The Ordering type class is often more convenient than Ordered in Scala—it allows you to specify how some existing type should be ordered without having to change its code or create a proxy class that extends Ordered[Whatever], which as you've seen can get messy very quickly.

Concise notation for single arg anonymous function (avoiding underscore) not working as expected

After going through some examples on the web I realize that there is a way to write an anonymous function without the underscore when only a single arg. Also, I'm experimenting with the "span" method on List, which I never knew existed. Anyway, here is my REPL session:
scala> val nums = List(1, 2, 3, 4, 5)
nums: List[Int] = List(1, 2, 3, 4, 5)
scala> nums span (_ != 3)
res0: (List[Int], List[Int]) = (List(1, 2),List(3, 4, 5))
scala> nums span (3 !=)
res1: (List[Int], List[Int]) = (List(1, 2),List(3, 4, 5))
So far so good. But when I try to use the "less than" operator:
scala> nums span (_ < 3)
res2: (List[Int], List[Int]) = (List(1, 2),List(3, 4, 5))
scala> nums span (3 <)
res3: (List[Int], List[Int]) = (List(),List(1, 2, 3, 4, 5))
Why is this behaving differently?
scala> nums span (_ < 3)
res0: (List[Int], List[Int]) = (List(1, 2),List(3, 4, 5))
scala> nums span (3 >)
res1: (List[Int], List[Int]) = (List(1, 2),List(3, 4, 5))
3 < is a shortcut to 3 < _, which creates a partially applied function from method call.
It's behaving correctly:
scala> nums span (3 < _)
res4: (List[Int], List[Int]) = (List(),List(1, 2, 3, 4, 5))
The predicate is false for the first element of the list, so the first list returned by span is empty.
scala> nums span (3 < _)
res0: (List[Int], List[Int]) = (List(),List(1, 2, 3, 4, 5))
// is equivalent to
scala> (nums takeWhile{3 < _}, nums.dropWhile{3 < _})
res1: (List[Int], List[Int]) = (List(),List(1, 2, 3, 4, 5))
where
the predicate is false already for the first element(1) therefore nums.takeWhile{false} results in the empty list List()
For the second part nothing is dropped because the predicate is false already for the first
element(1) and therefore the nums.dropWhile{false} is the whole list List(1, 2, 3, 4, 5).