Saturday, 30 December 2017

Introduction to Scala - XVI

We continue the journey on Scala on the topic of Lists in this post. For all the work in this post, we will use Read-Evaluate-Print-Loop Scala interpreter. Some familiarity with Java will be of great help in understanding Scala. In this post, we will look at how Lists are defined along with some features of Lists in Scala.

A List in Scala is a immutable set of ordered elements.

Ways to create a list:

1) An empty list holding integer elements 

val List0: List[Int] = List()

The results are shown below:

scala> val List0: List[Int] = List()
List0: List[Int] = List()

scala> List0
res23: List[Int] = List()


2) A List with initialized values:

scala> val List1: List[Int] = List(1,2,3,4,5)
List1: List[Int] = List(1, 2, 3, 4, 5)


scala> val List2: List[Int] = List(5,6,7,8,9,10)
List2: List[Int] = List(5, 6, 7, 8, 9, 10)


3) Using :: as shown below:

 scala> val List3 = 1 :: 3 :: 5 :: 7 :: 9 :: List()
List3: List[Int] = List(1, 3, 5, 7, 9)

scala> List3
res28: List[Int] = List(1, 3, 5, 7, 9)


There are many operations that can be performed that are common with Arrays, Vectors, Sets and Maps. In this post, we will look at some operations.

1)  :+ : Adds an element to List

 scala> List0
res38: List[Int] = List()

scala> List0 :+ 1
res39: List[Int] = List(1)

scala> List0 :+ 1 :+ 2
res40: List[Int] = List(1, 2)

scala> List0 :+ 1 :+ 2 :+ 3
res41: List[Int] = List(1, 2, 3)


2) :: : Adds an element to beginning of list

scala> List1 :: 6
<console>:13: error: value :: is not a member of Int
       List1 :: 6
             ^

scala> 6 :: List1
res44: List[Int] = List(6, 1, 2, 3, 4, 5)

scala> List1.::(6)
res45: List[Int] = List(6, 1, 2, 3, 4, 5)


3) ::: : Appends a given list

scala> List1
res51: List[Int] = List(1, 2, 3, 4, 5)

scala> List2
res52: List[Int] = List(5, 6, 7, 8, 9, 10)

scala> List1 ::: List2
res53: List[Int] = List(1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10)


4) combinations : Returns a iterator for various combinations of elements. Very similar to valuesIterator in Maps

scala> val List1_Iterator1 = List1.combinations(4)
List1_Iterator1: Iterator[List[Int]] = non-empty iterator

scala> while (List1_Iterator1.hasNext) {
     |   println(List1_Iterator1.next())
     | }
List(1, 2, 3, 4)
List(1, 2, 3, 5)
List(1, 2, 4, 5)
List(1, 3, 4, 5)
List(2, 3, 4, 5)


5) corresponds : Returns a boolean based on conditional comparison of two lists

scala> val List1: List[Int] = List(1,2,3,4,5)
List1: List[Int] = List(1, 2, 3, 4, 5)

scala> val List4: List[Int] = List(6,7,8,9,10)
List4: List[Int] = List(6, 7, 8, 9, 10)

scala> List1.corresponds(List4)((x,y) => (x+1) == y)
res63: Boolean = false

scala> List1.corresponds(List4)((x,y) => (x+5) == y)
res64: Boolean = true


6) dropWhile : Returns the longest predicate that satisfies a condition

scala> List1
res76: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.dropWhile(_ < 4)
res77: List[Int] = List(4, 5)


7) endsWith : Returns a boolean based on if the list matches end elements of a comparison list

scala> List1
res79: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.endsWith(List(4,5))
res80: Boolean = true


8) flatMap : Returns a List after applying a function

scala> List1
res103: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.flatMap(x => List(x*x))
res104: List[Int] = List(1, 4, 9, 16, 25) 


9) foreach : Returns a List after applying a function

scala> List1
res109: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.foreach(x=>println(x*x))
1
4
9
16
25


10)  isDefinedAt: Returns boolean if that index is valid

scala> List1
res113: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.isDefinedAt(3)
res114: Boolean = true

scala> List1.isDefinedAt(6)
res115: Boolean = false

  
11) map : Returns a List after applying a function

scala> List1
res116: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.map(x => x*x)
res117: List[Int] = List(1, 4, 9, 16, 25)


12)  maxBy : Returns element that will return maximum value when a function is applied

scala> List1
res119: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.maxBy(x => x*x)
res120: Int = 5


13)  permutations : Returns different permutations

scala> val List1_Iterator1 = List(1,2,3).permutations
List1_Iterator1: Iterator[List[Int]] = non-empty iterator

scala> while (List1_Iterator1.hasNext) {
     |   println(List1_Iterator1.next())
     | }
List(1, 2, 3)
List(1, 3, 2)
List(2, 1, 3)
List(2, 3, 1)
List(3, 1, 2)
List(3, 2, 1)


14) prefixLength : Returns length of largest predicate that satisfies a condition

scala> List1.prefixLength(_ < 3)
res124: Int = 2


15) reduce : Returns result after reduction of elements using a associative binary operator

scala> List1
res126: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.reduce((x,y) => x+y)
res127: Int = 15


16) reverseMap : Map in reverse order

scala> List1
res128: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.reverseMap(x=>x*x)
res129: List[Int] = List(25, 16, 9, 4, 1)


17) reverse_::: : Returns a reverse of list followed by second operand list

scala> List1
res130: List[Int] = List(1, 2, 3, 4, 5)

scala> List2
res131: List[Int] = List(5, 6, 7, 8, 9, 10)

scala> List1 reverse_::: List2
res132: List[Int] = List(5, 4, 3, 2, 1, 5, 6, 7, 8, 9, 10)


18) sameElements : Returns boolean if the elements in second list is same as that in first list

scala> List1
res134: List[Int] = List(1, 2, 3, 4, 5)

scala> List1 sameElements List1
res135: Boolean = true


19) segmentLength: Returns length of longest segment that satisfies a condition starting at an element

scala> List1
res137: List[Int] = List(1, 2, 3, 4, 5)

scala> List1 segmentLength (x => (x>=1 & x <=4), 0)
res138: Int = 4


20) size : Returns length of list

scala> List1
res141: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.size
res142: Int = 5


21) toString : Returns a string

scala> List1
res149: List[Int] = List(1, 2, 3, 4, 5)

scala> List1.toString
res150: String = List(1, 2, 3, 4, 5)


This concludes the discussion of Lists in Scala