------------------------------- Soluzione esercizio 18 https://season-lab.github.io/PFP/eserc/esercScala object E18Main extends App { def filterByIndex[T](l:List[T], f:Int=>Boolean) = { def rec(l:List[(T,Int)]):List[T] = { l match { case Nil => Nil case (x,i)::t if (f(i)) => x :: rec(t) case _::t => rec(t) } } rec(l.zipWithIndex) } def filterByIndex2[T](l:List[T], f:Int=>Boolean) = l.zipWithIndex.filter(c=>f(c._2)).map(c=>c._1) val l = "zero" :: "uno" :: "due" :: "tre" :: Nil; val p = filterByIndex(l, _%2==1) val q = filterByIndex2(l, _%2==1) println(l) println(p) println(q) } ------------------------------- Definizione di classi Versione Java: class Point { private double x,y; public double getX() { return x; } public double getY() { return x; } public Point(double x, double y) { this.x = x; this.y = y; } @override public String toString() { return "("+x+","+y+")"; } } Versione Scala: class Point(val x:Double,val y:Double) { override def toString = "("+x+","+y+")" } // ho x,y come var di istanza private // val inoltre genera automagicamente // due metodi getter con lo stesso nome // delle corrispondenti variabili di istanza // (criterio di naming uniforme) Programma di prova: object PointMain extends App { val p = new Point(2.3, 9.6) println(p) } ------------------------------- Costruttori ausiliari, operatori, classi object ereditarietà: class Point(val x:Double,val y:Double) { override def toString = "("+x+","+y+")" def mod = Math.sqrt(x*x+y*y) def this() = this(0,0) //val PI = 3.14 // <------ ? def +(other:Point) = new Point(x+other.x, y+other.y) } object Point { // companion object of class Point val PI = 3.14 } class Point3D(x:Double, y:Double, val z:Double) extends Point(x,y) { override def toString = "("+super.toString+","+z+")" // override def toString = "("+x+","+y+","+z+")" override def mod = Math.sqrt(x*x+y*y+z*z) } Programma di prova: object PointMain extends App { val p = new Point(2.3, 9.6) val q = new Point() val t = new Point3D(2.5,0.7,9.4) val s = p + q // equivalente a p.+(q) println(p + " " + p.mod) println(q + " " + q.mod) println(t + " " + t.mod) println(s + " " + s.mod) println(Point.PI) } ------------------------------- Metodo main, esecuzione corpo di un object, pericoli del dimenticare = nel def object MyMain { def main(s:Array[String]) = { println("due") } def somma1(x:Int, y:Int) { // errato: manca "=", quindi tipo restituito è Unit x+y } def somma2(x:Int, y:Int) = { // ok, tipo restituito è Int x+y } println("uno") } ------------------------------- Data analytics su liste con costrutti funzionali class Coder(val name:String, val age:Int) object CoderMain extends App { val l = List( new Coder("Anna", 19), new Coder("Paolo", 24), new Coder("Francesca", 21), new Coder("Marco", 22), new Coder("Lucia", 18) ) // trova nome coder più giovane val q = l.reduce((a,b)=>if (a.age Nil case (Nil,_) => Nil case (_,Nil) => Nil case (h1::t1, l2) if (l2 contains h1) => h1 :: inters(t1,l2) case (h1::t1, l2) => inters(t1,l2) } println(inters(List(1,2,3,4), List(5,6,3,9,4))) }