Friday, December 30, 2011

Learning Scala : Reading the exotic and essential List API scaladoc 9

Authored by Win Myo Htet


def apply (n: Int): A
Selects an element by its index in the list.

def canEqual (that: Any): Boolean
Method called from equality methods, so that user-defined subclasses can refuse to be equal to other collections of the same kind.

def collect [B] (pf: PartialFunction[A, B]): List[B]
[use case] Builds a new collection by applying a partial function to all elements of this list on which the function is defined.

def collect [B, That] (pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That]): That
Builds a new collection by applying a partial function to all elements of this list on which the function is defined.

def collectFirst [B] (pf: PartialFunction[A, B]): Option[B]
Finds the first element of the list for which the given partial function is defined, and applies the partial function to it.

def combinations (n: Int): Iterator[List[A]]
Iterates over combinations.

def companion : GenericCompanion[List]
The factory companion object that builds instances of class List. (or its Iterable superclass where class List is not a Seq.)
apply's description is good enough and I don't think that I have to explain it. apply can also be invoked without the function name. One can read more about it in my case class blog(companion object). canEqual is for us to override for our own class, where we can defined if we are to allow two elements to evaluate  equality. List does not override it. If we look at IterableLike (line 292), from which canEqual is inherited, it simply returns true. So, List allows to do equality for all type. collect takes Partial Functions that is constructed how we we collect the elements. collectFirst just picks the nicely-wrapped-in-Option first element from the collect. combinations can be used to create Lists that has exactly the number, which is received from  combinations's parameter, of elements from the invoking List object. companion function return a factory like class GenericCompanion from which one can create a new collection of the type like List. It is explained quite nicely at SO here.
scala> val list=List(1,2,3,4,5,6,7,8,9,10)
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.apply(0)
res0: Int = 1

scala> list(0)
res1: Int = 1

scala> list.canEqual("anything")
res2: Boolean = true

scala> val even:PartialFunction[Int,Int]={case x:Int if x%2==0 =>x}
even: PartialFunction[Int,Int] = <function1>

scala> list collect even
res3: List[Int] = List(2, 4, 6, 8, 10)

scala> val pretty_even:PartialFunction[Int,String]={case x:Int if x%2==0 =>"-"+x+"-"}
pretty_even: PartialFunction[Int,String] = <function1>

scala> list collect pretty_even
res4: List[String] = List(-2-, -4-, -6-, -8-, -10-)

scala> list collectFirst pretty_even
res5: Option[String] = Some(-2-)

scala> val strList=list.companion("a","b","c","d")
strList: List[java.lang.String] = List(a, b, c, d)

scala> for(x <- strList.combinations(2)) println(x)
List(a, b)
List(a, c)
List(a, d)
List(b, c)
List(b, d)
List(c, d)

scala> for(x <- strList.combinations(3)) println(x)
List(a, b, c)
List(a, b, d)
List(a, c, d)
List(b, c, d)

scala> 


We have covered compose, so let's look at the other functions start with C.
def contains (elem: Any): Boolean
Tests whether this list contains a given value as an element.

def containsSlice [B] (that: Seq[B]): Boolean
def containsSlice [B] (that: GenSeq[B]): Boolean
Tests whether this list contains a given sequence as a slice.

def copyToArray (xs: Array[A], start: Int, len: Int): Unit
[use case] Copies elements of this list to an array.
def copyToArray [B >: A] (xs: Array[B], start: Int, len: Int): Unit
Copies elements of this list to an array.
def copyToArray (xs: Array[A]): Unit
[use case] Copies values of this list to an array.
def copyToArray [B >: A] (xs: Array[B]): Unit
Copies values of this list to an array.
def copyToArray (xs: Array[A], start: Int): Unit
[use case] Copies values of this list to an array.
def copyToArray [B >: A] (xs: Array[B], start: Int): Unit
Copies values of this list to an array.

def copyToBuffer [B >: A] (dest: Buffer[B]): Unit
Copies all elements of this list to a buffer.

def corresponds [B] (that: Seq[B])(p: (A, B) ⇒ Boolean): Boolean
def corresponds [B] (that: GenSeq[B])(p: (A, B) ⇒ Boolean): Boolean
Tests whether every element of this list relates to the corresponding element of another sequence by satisfying a test predicate.

def count (p: (A) ⇒ Boolean): Int
Counts the number of elements in the list which satisfy a predicate.
contains is simple. containsSlice needs the sequenced slice as we will see that evenlist return false. There are quite a lot of copyToArray functions. copyToArray is self explanatory name but still the keyword, we usually need to look for reading such functions, is [use case]. In this case, the adequate description is provided for all the functions and we won't be going over the detail but run some code snippet. copyToBuffer needs us to use ListBuffer. The reason that it is not explicitly stated and that a lot of functions description is that the document is generated from the comments from the source code where a lot of other classes also inherit the same functions. If we go look at TraversableOnce source line 219, you will see the description for copyToBuffer. If we also look at all the sub classes, which inherit from TraversableOnce, we will see the reason why the descriptions of the functions are very generic. correponds checks if the other collections have the same elements. count checks the number of element that satisfies the predicate. In our case, it is even test.
scala> val list=List(1,2,3,4,5,6,7,8,9,10)
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.contains(1)
res0: Boolean = true

scala> list.contains("a")
res1: Boolean = false

scala> val taillist=list tail
taillist: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val even:PartialFunction[Int,Int]={case x:Int if x%2==0 =>x}
even: PartialFunction[Int,Int] = <function1>

scala> val evenlist=list collect even
evenlist: List[Int] = List(2, 4, 6, 8, 10)

scala> list containsSlice taillist
res2: Boolean = true

scala> list containsSlice evenlist
res3: Boolean = false

scala> val tailarray = taillist toArray
tailarray: Array[Int] = Array(2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list containsSlice tailarray
res4: Boolean = true

scala> val array=new Array[Int](10)
array: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

scala> list.copyToArray(array,3,5)

scala> array
res6: Array[Int] = Array(0, 0, 0, 1, 2, 3, 4, 5, 0, 0)

scala> list.copyToArray(array)

scala> array
res8: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val arrayAny=new Array[Any](8)
arrayAny: Array[Any] = Array(null, null, null, null, null, null, null, null)

scala> list.copyToArray(arrayAny)

scala> arrayAny
res10: Array[Any] = Array(1, 2, 3, 4, 5, 6, 7, 8)

scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

scala> val listbuffer=new ListBuffer[Int]()
listbuffer: scala.collection.mutable.ListBuffer[Int] = ListBuffer()

scala> list.copyToBuffer(listbuffer)

scala> listbuffer
res12: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val array=list.toArray
array: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.corresponds(array){(le,ae)=>le==ae}
res13: Boolean = true

scala> list.count{a => a%2==0}
res14: Int = 5
After we learn C, we learn D, right?


Authored by Win Myo Htet

No comments:

Post a Comment