140 likes | 148 Views
Case Classes. HW4 Review. Case Classes. Why? Immutable classes with ctor parameters. Easier than defining setters and getters and a class for them. Reduces Boilerplate from J2EE EJBs https://gist.github.com/dougc333/2975185224510197e005 How to move the common weight into abstract class?.
E N D
Case Classes HW4 Review
Case Classes • Why? Immutable classes with ctor parameters. Easier than defining setters and getters and a class for them. Reduces Boilerplate from J2EE EJBshttps://gist.github.com/dougc333/2975185224510197e005 • How to move the common weight into abstract class?
Case Class • abstract class CodeTree2 { • val name:String • def weight:Int • } • case class Fork3(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree • case class Leaf3(char: Char, weight: Int) extends CodeTree • object foo2 extends Application{ • val l3 = Leaf3('a',1) • println(l3.weight) • val f3 = Fork3(l3, Leaf3('b',2),List('c'),4) • println(f3.weight) • } • 1 • 4 • For weight move into ABC • def weight(tree: CodeTree): Int = { • tree.weight • }
Case classes • Autoimplement getters/setters & no instanceof needed. Return ivars from ctor args def chars(tree: CodeTree): List[Char] = tree match{ case Fork(_, _, chars, _) => chars case Leaf(char, _) => List(char) }
MakeCodeTree • Fork is for combining 2 CodeTrees, to add lists together use ++ or :::. def makeCodeTree(left: CodeTree, right: CodeTree) = Fork(left, right, chars(left) ++ chars(right), weight(left) + weight(right))
times • def times(chars: List[Char]): List[(Char, Int)] = { • def timesAcc(chars:List[Char],acc:Map[Char,(Char,Int)]):Map[Char,(Char,Int)] = chars match { • case Nil => acc • case x::xs => if (acc contains x) {val tmpacc=acc.updated(x,(x,acc(x)._2+1));timesAcc(xs,tmpacc)} else {val tmpacc=acc+(x->(x,1));timesAcc(xs,tmpacc)}; • } • timesAcc(chars,Map()).values.toList • } • This is a good time to practice. Reduce number of new things to learn. Remove pairs, remove return • Implement def times(chars:List[Chars]) and put in print statements to show what is happening
Iterating through list • //iterate through the list • def testMe2(chars:List[Char]):Unit={ • def testMe2Acc(chars:List[Char]) = chars match{ • case Nil => println("testMe2 match empty list") • case x::xs => println("testMe2 not empty List x:"+x+",xs:"+xs); testMe2(xs) • } • testMe2Acc(chars) • } • Write test code to verify your print statements match what is happening and you can iterate through the list.
Add accumulator • def testMe3(chars:List[Char]):Unit={ • def testMe3Acc(chars:List[Char],acc:Map[Char,Int]):Unit = chars match{ • case Nil => println("testMe3 match empty list") • case x::xs => println("testMe3 not empty List x:"+x+",xs:"+xs);println("acc:"+acc); if (acc contains x) {val tmpacc=acc.updated(x,acc(x)+1);println("contains acc after add+"+tmpacc);testMe3Acc(xs,tmpacc)} else {println("not contains adding");val tmpacc=acc+(x->1);print("acc after add:"+tmpacc);testMe3Acc(xs,tmpacc)}; • } • testMe3Acc(chars,Map()) • }
Add Pairs w/no return type • //make pairs, w/o return type • def testMe5(chars:List[Char]):Unit={ • def testMe5Acc(chars:List[Char],acc:Map[Char,(Char,Int)]):Unit = chars match{ • case Nil => println("testMe5 empty list"); • case x::xs => println("testMe5 char:"+x);println("acc before insert:"+acc); if (acc contains x) {val tmpacc=acc.updated(x,(x,acc(x)._2+1));println("tmpacc+"+tmpacc);testMe5Acc(xs,tmpacc)} else {println("not contains adding");val tmpacc=acc+(x->(x,1));print("acc after add:"+tmpacc);testMe5Acc(xs,tmpacc)}; • } • testMe5Acc(chars,Map()) • }
Add map return and convert to list • def testMe6(chars:List[Char]):List[(Char,Int)]={ • def testMe6Acc(chars:List[Char],acc:Map[Char,(Char,Int)]):Map[Char,(Char,Int)] = chars match{ • case Nil => println("testMe6 empty list");acc • case x::xs => println("testMe6 char:"+x);println("acc before insert:"+acc); if (acc contains x) {val tmpacc=acc.updated(x,(x,acc(x)._2+1));println("tmpacc+"+tmpacc);testMe6Acc(xs,tmpacc)} else {println("not contains adding");val tmpacc=acc+(x->(x,1));print("acc after add:"+tmpacc);testMe6Acc(xs,tmpacc)}; • } • testMe6Acc(chars,Map()).values.toList • }
Final answer for times • def times(chars: List[Char]): List[(Char, Int)] = { • def timesAcc(chars:List[Char],acc:Map[Char,(Char,Int)]):Map[Char,(Char,Int)] = chars match { • case Nil => acc • case x::xs => if (acc contains x) {val tmpacc=acc.updated(x,(x,acc(x)._2+1));timesAcc(xs,tmpacc)} else {val tmpacc=acc+(x->(x,1));timesAcc(xs,tmpacc)}; • } • timesAcc(chars,Map()).values.toList • }
Sort list then convert Pairs to leaf • def makeOrderedLeafList(freqs: List[(Char, Int)]): List[Leaf] = • { • freqs.sortBy(Tuple2 => Tuple2._2).map(Tuple2 => Leaf(Tuple2._1, Tuple2._2)) • }
Singleton • def singleton(trees:List[CodeTree]):Boolean ={ • if (trees.length == 1) true • false • }
Combine, 2 examples • Tree match & no tree match def combine(trees: List[CodeTree]): List[CodeTree] = trees match{ case first::second::restofList => { val ct = makeCodeTree(first,second) val large = trees.filter(x=>weight(x)>weight(ct)) return ct::large } case _ => println("less than 2"); trees //if less than 2 return trees } def combine2(trees: List[CodeTree]): List[CodeTree] = { if (trees.length>=2) { val ct = makeCodeTree(trees.head,trees(2)) val large = trees.filter(x=>weight(x)>weight(ct)) return ct::large } trees }