scala – List – zip , unzip

The zip operation takes two lists and forms a list of pairs:

If the two lists are of different length, any unmatched elements are dropped:

 

A useful special case is to zip a list with its index. This is done most efficiently with the zipWithIndex method, which pairs every element of a list with the position where it appears in the list.

Any list of tuples can also be changed back to a tuple of lists by using the unzip method:

object List_Zip_Unzip extends App {

//  If the two lists are of different length, any unmatched elements are dropped:

  val lst=List('a','b','c')

  val lstzip=lst.indices zip lst
  println(lstzip)
  //scala.collection.immutable.IndexedSeq[(Int, Char)] 

  val lstindex=lst.zipWithIndex
  println(lstindex)
// List[(Char, Int)] 

println(lstindex.unzip)

}


Vector((0,a), (1,b), (2,c))
List((a,0), (b,1), (c,2))
(List(a, b, c),List(0, 1, 2))

scala – List – flatten

flatten method takes a list of lists and flattens it out to a single list:

It can only be applied to lists whose elements are all lists. Trying to flatten any other list will give a compilation error:

 

object List_Flatten extends App{

  val lst = List(List(1, 2), List(3), List(), List(4, 5)).flatten
println(lst)

  val ctry=List("america","india")
  val chr=ctry.map(_.toCharArray).flatten
  println(chr)
}


List(1, 2, 3, 4, 5)
List(a, m, e, r, i, c, a, i, n, d, i, a)

scala – List – reverse

like all other list operations, reverse creates a new list rather than changing the one it operates on. Lists are immutable

Reverse could be implemented using concatenation(:::),like in the following method, rev:
def rev[T](xs: List[T]): List[T] = xs match

{

case List() => xs

case x :: xs1 => rev(xs1) ::: List(x)

}

To study the complexity of rev, assume that the list xs has length n. Notice that there are n recursive calls to rev. Each call except the last involves a list concatenation. List concatenation xs ::: ys takes time proportional to the length of its first argument xs. Hence, the total complexity of rev is: n+(n−1)+…+1 = (1+n)∗n/2

rev’s complexity is quadratic in the length of its input argument. This is disappointing when compared to the standard reversal of a mutable, linked list, which has linear complexity

Scala – Concatenate – by pattern matching

def append[T](xs: List[T], ys: List[T]): List[T] = xs match {

case List() => ys

case x :: xs1 => x :: append(xs1, ys)

}

So it will take the two lists to be concatenated as parameters. These two lists must agree on their element type, but that element type can be arbitrary.

This can be expressed by giving append a type parameter that represents the element type of the two input lists:
def append[T](xs: List[T], ys: List[T]): List[T]

Since lists are constructed from the back towards the front, ys can remain intact whereas xs will need to be taken apart and prepended to ys.

Thus, it makes sense to concentrate on xs as a source for a pattern match.

The most common pattern match over lists simply distinguishes an empty from a non-empty list

Scala – List – concatenation (:::)

Concatenation (::: ) is implemented as method in class List

The result of xs ::: ys is a new list that contains all the elements of xs, followed by all the elements of ys.

Like cons, list concatenation associates to the right

xs ::: ys ::: zs
is interpreted like this:
xs ::: (ys ::: zs)

 

object List_Concatenation extends App{

  val l1 =List(1,2,3)
  val l2=List(3,4,5)
  val l3=l1:::l2

  println(l3)
  println(l3:::Nil)

  println(List():::l3)
  println(List(1,2,3):::List(4))
}