/*
Topic 1. Liste (din Scala).
*/
val l = List(1,2,3)
//Cons(1,Cons(2,Cons(3,Void)))
1 :: 2 :: 3 :: Nil
List(1,2,3) match {
case Nil => 0
case x :: y :: Nil => 2
case x :: y :: _ => 3
case x :: xs => 1
}
// listele sunt orientate obiect
l.head // 1
l.tail //
l.map(_*2) // transformare per element
l.foldRight(0)(_ + _)
// 1 + (2 + (3 + acc)))
l.foldLeft(Nil:List[Int])((acc,x) => x :: acc)
// (acc op 1) op 2) op 3
val lp = List((1,2), (3,1), (4,4))
lp.sortBy(_._2)
lp.sortBy(x => x._1 + x._2)
/* notatia infix*/
trait Nat {
def +(other: Nat): Nat
def -(other: Nat): Nat
}
case object Zero extends Nat {
override def +(other: Nat): Nat = other
override def -(other: Nat): Nat = Zero
}
case class Succ(n: Nat) extends Nat {
override def +(other: Nat): Nat = Succ(n + other)
override def -(other: Nat): Nat =
other match {
case Zero => this
case Succ(np) => n - np
}
}
val x = Succ(Zero)
val y = Succ(Succ(Zero))
x + y
/*
In Scala, expresia:
token1 token2 token3 se citeste:
token1.token2(token3), cu conditia ca:
token1 sa fie un obiect
token2 sa fie o functie membru a clasei obiectului resp.
token3 sa fie un parametru
*/
x.-(y)
x - y
List(1,2,3) map (_+1)
List(1,2,3).map(_+1)
val f = ((x: Int) => x + 1) andThen
(_*2) andThen
(_-1)
f(1)
val emails =
List("matei@gmail.com", "mihai@gmail.com", "ana@gmail.com", "john@yahoo.com", "mary@aol.com", "maria@upb.ro")
/* vrem sa aflam frecventa cu care apare un domeniu in lista de mai sus */
/* sa zicem ca ne intereseaza frecventa pt domeniul gmail */
// Cum implementam (abordam) aceasta problema FUNCTIONAL?
"Test".toList
/*
This function will be included later in the final implementation:
def getDomain(email: List[Char]): List[Char] =
email match {
case '@' :: xs => xs
case _ :: xs => getDomain(xs)
}
getDomain("Matei@gmail.com".toList)
*/
type Str = List[Char]
def getFrequencies(emails: List[String]): List[(String,Int)] = {
def getDomain(email: Str): Str =
email match {
case '@' :: xs => xs
case _ :: xs => getDomain(xs)
}
def join(domain: Str): String =
domain.foldRight("")(_ + _) // introducerea unui caracter intr-un string
/*
recursive variant for groupLists. We prefer writing is using foldRight, as below:
def groupLists(l: List[String]): List[List[String]] =
l match {
case Nil => Nil
case x :: xs => {
val r = groupLists(xs)
if (x == r.head.head) (x :: r.head) :: r.tail
else (x :: Nil) :: r
}
}*/
def groupLists(l: List[String]): List[List[String]] =
l.foldRight(Nil:List[List[String]])((domain,acc) =>
if (acc == Nil) List(domain)::Nil
else if (domain == acc.head.head) (domain :: acc.head) :: acc.tail
else (domain :: Nil) :: acc
)
// the outer set of parentheses are mandatory, in order to express where does the andThen sequence end
val sequence =
(((l: List[String]) => l.map(_.toList)) // make each String into a Str (List[Char])
andThen (_.map(getDomain(_))) // extract the domain from each Str
andThen (_.map(join(_))) // convert to String back again
andThen (_.sortBy(x => x)) // sort the list of domains
andThen (groupLists(_)) // group identical domains
andThen (_.map(group => (group.head,group.size)))) // transform each group into a frequency pair
sequence(emails)
}
getFrequencies(emails)
/*
def groupLists(l: List[String]): List[List[String]] =
l match {
case x :: Nil => List(x) :: Nil
case x :: xs => {
val r = groupLists(xs)
if (x == r.head.head) (x :: r.head) :: r.tail
else (x :: Nil) :: r
}
}
*/