Reputation: 83
I'm trying to write the get method for a key, value pair implemented using a list. I want to use the Option type as I heard its good for this but I'm new to Scala and I'm not really sure how to use it in this case...
This is as far as I got, only the method header.
def get(key : String): Option[Any] = {}
Upvotes: 2
Views: 3083
Reputation: 1124
Although @Marius' collectFirst
version is probably the most elegant (and maybe a little bit faster as it only uses one closure), I find it more intuitive to use find
for your problem :
def get[A, B](key: A, pairs: List[(A, B)]): Option[B] = pairs.find(_._1 == key).map(_._2)
In case you were wondering (or need high performance), you will need either @Marius' recursive or the following imperative version which may look more familiar (although less idiomatic):
def get[A, B](key: A, pairs: List[(A, B)]): Option[B] = {
var l = pairs
var found: Option[B] = None
while (l.nonEmpty && found.isEmpty) {
val (k, v) = l.head
if (k == key) {
found = Some(v)
} else {
l = l.tail
}
}
found
}
What you must understand is that Option[B]
is a class that may either be instantiated to None
(which replaces and improves the null
reference used in other languages) or Some(value: B)
. Some
is a case class, which allows, among other neat features, to instantiate it without the new
keyword (thanks to some compiler magic, Google Scala case class for more info). You can think of Option
as a List
which may contain either 0 or 1 element: most operations that can be done on sequences can also be applied to Option
s (such as map
in the find
version).
Upvotes: 0
Reputation: 4007
You can turn a List of Pairs into a Map:
class Store[K, V](values: List[(K, V)]) {
val map = values.toMap
def get(key: K): Option[V] = map get key
}
Upvotes: 0
Reputation: 10401
My guess is you are looking for something like this:
class KeyValueStore(pairs: List[(String, Any)]) {
def get(key: String): Option[Any] = pairs.collectFirst {
case (k, v) if k == key => v
}
}
This uses the collectFirst
method for sequences. If you want a more "do it yourself" approach, this should work:
def get(key: String): Option[Any] = {
def search(xs: List[(String, Any)]): Option[Any] = {
xs match {
case List() => None //end of list and key not found. We return None
case (k, v) :: rest if k == key => Some(v) // found our key. Returning some value
case _ :: rest => search(rest) // not found until nou. Carrying on with the rest of the list
}
search(pairs)
}
}
Upvotes: 3