Thursday, August 1, 2013

Different Variant of the Custom (typed) Map implementation


trait MyMap[K,V]{
def +(k:K,v:V):MyMap[K,V]
def get(x:K):V
def keys:List[K]
def values:List[V]
def length:Int
}
object MyMap {

def apply[K,V](x:Tuple2[K,V]*): MyMap[K,V] = new MyMapImpl[K,V](x.toList);
class MyMapImpl[K,V](xs:List[Tuple2[K,V]]) extends MyMap[K,V] {

def +(k:K,v:V):MyMap[K,V] = new MyMapImpl[K,V](Tuple2(k,v)::xs)
def get(k:K):V = (xs find (m=>m._1==k)) match {
case Some(x) => x._2
}
def keys:List[K] = xs map (m=>m._1)
def values:List[V] = xs map (m=>m._2)
def length:Int = xs length
}

}

def myTest {

var x = MyMap((1,2),(3,4),(33,56))
println(x  get 33)

x += (35,44) // Adds a new (key, value) pair to the map x
println(x get 35) // Prints 44 (value)

println("Keys-->>"+x.keys.toString) // prints List(1,3,33)
println("Values-->>"+x.values.toString) // prints List(2,4,56,44)
println("Length-->>"+x.length) // prints 4 which is the size of the custom typed map.
}
myTest


Explanation:

My previous version of the custom (typed) map implementation -->>http://dailyscala.blogspot.com/2013/06/create-your-own-typed-map-in-scala.html

The example in the link above uses more imperative style in implementing the map methods but Scala provides many functional ways to implement the + , get, keys and values methods. Lets take them one by one

1)The + method takes two inputs (a,b) where a is the key and b is the value. The implementation takes these two values, converts them into a tuple of the form Tuple2[K,V] and cons (::) it to the original list and returns it. The type of the list returned will be List[Tuple2[K,V]]

2) The "get" method is the most interesting part of the program. This method takes input of type K (here it is "k"), which is the key and returns a value of type V, which is the value. The find operation is called on the current list and the predicate used processes each element of the list (which is a Tuple2), extracts the first element using the ._1 method and compares it with the key "k". The find returns the first element of the list which satisfies the predicate. The returned element will be of the type Option or more specifically Option[Tuple2[K,V]]. Next, this Option value is piped into a pattern match block and the value is matched against Some(x) and the value x is returned as the matching value to the key "k".

3) The "keys" method returns a list of all the keys inside the custom implemented Map. The implementation of this method is as follows=> The map method is applied to the list of tuples. A map applies a predicate to all the elements of the list. The predicates converts the element to a different form.
For e.g: List(1,2,3) map _+1  will return the list List(2,3,4). Here each element of the list is converted to a different element using the predicate "_+1". Similarly, in the custom map, each element of the list (Tuple2) is converted into a type K using the predicate "m=>m._1". Here "m" is the Tuple and m._1 is the first value of the Tuple, which is the "key". The new list of all the converted values is returned. The type of the returned list will be List[K]

4) The "values" method also is similarly written as the "keys" method above.





No comments:

Post a Comment