在值满足函数的映射中查找键

时间:2016-11-25 16:11:15

标签: scala

我是函数式编程的新手,我正在使用scala。我目前正在为我的大学课程编写一个程序。

我输入了以下地图:

    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)
    )

我正在尝试输出包含最大增量的密钥(股票代码)。

我已设法使用以下代码找到最大增量:

    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)

我以为我就在那里,直到我发现我必须输出与计算出的最大增量相对应的密钥。

考虑使用getOrElse,但我确实不确定,因为我是scala和函数式编程的初学者。

我希望这是有道理的,如果我需要澄清任何事情,请告诉我。

由于

1 个答案:

答案 0 :(得分:3)

您可以使用模式匹配计算最后两个元素:

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")
  }

首先它匹配a +: b +: Nil,如果tail是列表的末尾,则提取两个第一个元素。如果它不能匹配这种情况,它会尝试将列表分解为head +:tail,因此它可以递归调用尾部。如果先使用空列表调用它,则会抛出异常。

然后,对于mapdata中的每个条目,您可以计算最近的两个元素,然后减去它们:

val increases = 
  for {
    (k, v) <- mapdata
    (a, b) = mostRecent(v)
  } yield (k, b - a)

作为最后一步,您可以使用maxBy方法找到最大值:

val max = increases.maxBy(_._2) 
max: (String, Int) = ("SK4", 7)