在地图列表中查找大于*的值

时间:2016-11-14 21:06:38

标签: scala list search

我当前的系统是一个映射的String,List [Int],String是一个键值," Sk1"," Sk2"等等,int是0-9的数字列表。

以下是我目前查找所有列表的方法,如何编辑此列表以仅查找所有" Sk *" s大于所选的" SK *&#34 ;。列表的值是尾部的最后一个元素,我已经有了一个函数可以找到。它是handleFive选项菜单。为了澄清,我需要找到最后一个元素(已经具有该功能),然后只显示大于所选股票的股票。

菜单选项的处理程序

  def handleFive(): Boolean = {
    mnuShowSingleDataStock(currentStockLevel)
    true
  }

  def handleSeven(): Boolean = {
    mnuShowPointsForStock(allStockLevel)
    true
  }

调用用户并与用户交互的函数

// Returns a single result, not a list
  def mnuShowSingleDataStock(f: (String) => (String,Int)) = {
    print("Stock > ")
    val data = f(readLine)
    println(s"${data._1}: ${data._2}")
  }

//Returns a list value
  def mnuShowPointsForStock(f: (String) => (String,List[Int])) = {
    print("Stock > ")
    val data = f(readLine)
    println(s"${data._1}: ${data._2}")
  }

不知道如何编辑它,目前它显示列表中的所有值,我只想返回大于所选值的值

  //Show last element in the list, most current
  def currentStockLevel (stock: String): (String, Int) = {
    (stock, mapdata.get (stock).map(findLast(_)).getOrElse(0))
  }

//Unsure how to change this to only return values greater than the selected one, not everything
  def currentStockLevel (stock: String): (String, List[Int]) = {
    (stock, mapdata.get (stock).map(findLast(_)).getOrElse(0))
  }

我当前的映射列表 - 这是MAPDATA

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, 8),
    "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)
  )

2 个答案:

答案 0 :(得分:2)

Map[String, List[Int]]类型有一个filterKeys(f: String => Boolean)方法,以便只保留满足给定谓词的键。

可能的解决方案是

// get int value from stock if of the form "SK<int>"
def stockInt(stock: String): Option[Int] = 
  Try(stock.drop(2).toInt).filter(_ => stock.startsWith("SK")).toOption

// we keep the keys in the return, so that you do not get unordered results
// (order is not assured by Map)
def currentStockLevel(stock: String): (String, Map[String, Int]) = {
  val maybeN = stockInt(stock)
  def isGreater(other: String) = (for {
    o <- stockInt(other)
    n <- maybeN
  } yield o > n).getOrElse(true) // if any key is not in the form of SK*, assume it is greater than the original stock

  (
    stock, 
    mapdata.filterKeys(isGreater(_)).mapValues(findLast(_))
  )
}

另一种可能性,如果您确定只有“SK”键,则使用SortedMap,它使用SortedSet作为其键,以确保您拥有键值对按照你想要的顺序排列。

在这种情况下,解决方案将是

//put all values in mapdata in a SortedMap
val sortedMap = SortedMap[String, List[Int]]() ++ mapdata

def currentStockLevel(stock: String): (String, List[Int]) = {
  (
    stock, 
    sortedMap.dropWhile(_ <= stock).toList.map(_._2).map(findLast(_))
  )
}

编辑(在评论预期的回报后):

如果我很清楚你想要做什么,你想要过滤值而不是键。这不是问题,Map也有filter(p: ((K, V)) => Boolean): Map[K, V]方法可以做到这一点:

def currentHigherStockLevel(stock: String): Map[String, Int] = {
  val current = datamap.get(stock).map(findLast).getOrElse(0) // if stock is not in the keySet, we keep all keys, by keeping those greater than 0.
  datamap.mapValues(findLast).filter {
    case (sk, val) => val > current
  }
}  

这会返回一个Map[String; Int],其中值是最后一个大于作为参数给出的值(我们保留它们的键,因为它们可能会有用)。

答案 1 :(得分:1)

如果关键字符串是"SK9""SK10"之类的内容,那么您必须将数字剪切掉,转换为Int,然后比较/过滤它们,但如果您的密钥保留以完全一致的格式:"SK001""SK002" ... "SK009""SK010" ... "SK099""SK100"等,然后你使用简单的字符串比较来过滤你想要的东西。

mapdata.filterKeys(_ >= stock).values  // an Iterable[List[Int]]