Reputation: 537
I am completely new to functional programming and I am working with scala. I am currently writing a program for my university coursework.
I have inputted the following map:
val mapdata = Map(
"SK1" -> List(9, 7, 2, 0, 7, 3, 7, 9, 1, 2, 8, 1, 9, 6, 5, 3, 2, 2, 7, 2, 8, 5, 4, 5, 1, 6, 5, 2, 4, 1),
"SK2" -> List(0, 7, 6, 3, 3, 3, 1, 6, 9, 2, 9, 7, 8, 7, 3, 6, 3, 5, 5, 2, 9, 7, 3, 4, 6, 3, 4, 3, 4, 1),
"SK3" -> List(8, 7, 1, 8, 0, 5, 8, 3, 5, 9, 7, 5, 4, 7, 9, 8, 1, 4, 6, 5, 6, 6, 3, 6, 8, 8, 7, 4, 0, 6),
"SK4" -> List(2, 9, 5, 7, 0, 8, 6, 6, 7, 9, 0, 1, 3, 1, 6, 0, 0, 1, 3, 8, 5, 4, 0, 9, 7, 1, 4, 5, 2, 9),
"SK5" -> List(2, 6, 8, 0, 3, 5, 5, 2, 5, 9, 4, 5, 3, 5, 7, 8, 8, 2, 5, 9, 3, 8, 6, 7, 8, 7, 4, 1, 2, 3),
"SK6" -> List(2, 7, 5, 9, 1, 9, 8, 4, 1, 7, 3, 7, 0, 8, 4, 5, 9, 2, 4, 4, 8, 7, 9, 2, 2, 7, 9, 1, 6, 9),
"SK7" -> List(6, 9, 5, 0, 0, 0, 0, 5, 8, 3, 8, 7, 1, 9, 6, 1, 5, 3, 4, 7, 9, 5, 5, 9, 1, 4, 4, 0, 2, 0),
"SK8" -> List(2, 8, 8, 3, 1, 1, 0, 8, 5, 9, 0, 3, 1, 6, 8, 7, 9, 6, 7, 7, 0, 9, 5, 2, 5, 0, 2, 1, 8, 6),
"SK9" -> List(7, 1, 8, 8, 4, 4, 2, 2, 7, 4, 0, 6, 9, 5, 5, 4, 9, 1, 8, 6, 3, 4, 8, 2, 7, 9, 7, 2, 6, 6)
)
I am trying to output the key (stock symbol) which contains the maximum increase.
I have managed to find the maximum increase using the following code:
def mostRecent(Is:List[Int]): Int = {
if (Is.tail == Nil)
return Is.head
else
mostRecent(Is.tail)
}
def penultimate(x: List[Int]): Int = x(x.length - 2)
//this definition allow me to subtract the mostRecentValues and the penultimate values
def subtractLast2(pen: Iterable[Int], last: Iterable[Int]): Iterable[Int] = {
pen zip last map(x => x._1 - x._2)
}
//outputs a list with containing the last values
val MostRecentPrices = mapdata.values.map(x => mostRecent(x))
//outputs a list with containing the second last values
val penultimatePrices = mapdata.values.map(x => penultimate(x))
//determines the maximum increase
val maxIncrease = (subtractLast2(MostRecentPrices, penultimatePrices)).max
//output the stock that has increased the most in the last day of the period
println("MaxIncrease = " + maxIncrease)
I thought I was just about there until I found out I had to output the key that corresponds with the calculated maximum increase.
Was thinking of using getOrElse but really not sure as I am a beginner in scala and functional programming.
I hope this makes sense, please let me know if I need to clarify anything.
Thanks
Upvotes: 2
Views: 155
Reputation: 1239
You can calculate two last elements by using pattern matching:
def mostRecent(is: List[Int]): (Int, Int) =
is match {
case a +: b +: Nil => (a, b)
case head +: tail => mostRecent(tail)
case Nil => throw new Exception("Can't calculate for an empty list")
}
First it matches on a +: b +: Nil
which extracts two first elements if tail is the end of the list. If it can't match this case, it tries to decompose the list as head +: tail, so it can call itself recursively for the tail. In case it was called with an empty list first it throws an exception.
Then, for every entry in mapdata
you can calculate the two most recent elements, and subtract them:
val increases =
for {
(k, v) <- mapdata
(a, b) = mostRecent(v)
} yield (k, b - a)
As a last step you can find maximum using maxBy
method:
val max = increases.maxBy(_._2)
max: (String, Int) = ("SK4", 7)
Upvotes: 3