2016-11-12 121 views
0

该文件的每一行用于构建以股票代码为关键字和整数列表作为值的映射条目。结构的类型是Map [String,List [Int]]。 目前我的系统可以搜索列表中的单个条目并显示不同的结果。我怎么会比较列表中的2? 如何比较此列表中的2个项目?请在我现在有的代码下面找到我的代码,我明白我应该提供代码供您评估,但我不确定如何启动此代码。任何和每个帮助表示赞赏。比较列表中的2个条目

/** 
    * Created by Andre on 10/11/2016. 
    */ 
import scala.io.Source 
import scala.io.StdIn.readInt 
import scala.io.StdIn.readLine 
import scala.collection.immutable.ListMap 
import scala.util.Try 

object StockMarket extends App { 

    // ******************************************************************************************************************* 
    // application logic 

    // read data from file 
    val mapdata = readFile("data.txt") 
    // print data to check it's been read in correctly 
    //println(mapdata) 

    // define menu options as a Map of actions 
    // for each menu item: 
    // key is an Int, the value that will be read from the input 
    // value is a function() => Boolean, i.e. no params and returns Boolean 
    val actionMap = Map[Int,() => Boolean](1 -> handleOne, 2 -> handleTwo, 3 -> handleThree, 4 -> handleFour, 5 -> handleFive, 6 -> handleSix, 8-> handleEight) 

    // loop to read input and invoke menu option 
    // uses function readOption to show menu and read input 
    // uses function menu to invoke menu action 
    // will terminate if menu returns false 
    var opt = 0 
    do { 
    opt = readOption 
    } while (menu(opt)) 



    // ******************************************************************************************************************* 
    // FUNCTIONS FOR MENU 

    // shows menu and reads input 
    def readOption: Int = { 
    println(
     """|Please select one of the following: 
     | 1 - show All stock levels 
     | 2 - Show Selected Stock Level 
     | 3 - Show Highest Stock Level 
     | 4 - Show Lowest Stock Level 
     | 5 - Show Current Stock Level 
     | 6 - Show Average Stock Level 
     | 8 - quit""".stripMargin) 
    readInt() 
    } 

    // invokes selected menu option 
    // finds corresponding function to invoke in action map using get 
    // pattern matching used as get returns an Option 
    def menu(option: Int): Boolean = { 
    actionMap.get(option) match { 
     case Some(f) => f() 
     case None => 
     println("Sorry, that command is not recognized") 
     true 
    } 
    } 

    // handlers for menu options 
    def handleOne(): Boolean = { 
    mnuShowPoints(currentPoints) 
    true 
    } 

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

    def handleThree(): Boolean = { 
    mnuShowSingleDataStock(highestStockLevel) 
    true 
    } 

    def handleFour(): Boolean = { 
    mnuShowSingleDataStock(lowestStockLevel) 
    true 
    } 

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

    def handleSix(): Boolean = { 
    mnuShowSingleDataStock(averageStockLevel) 
    true 
    } 

    def handleEight(): Boolean = { 
    println("selected quit") // returns false so loop terminates 
    false 
    } 





    // ******************************************************************************************************************* 
    // UTILITY FUNCTIONS 
    //GETS THE DATA FROM THE DATA.TXT 
    def readFile(filename: String): Map[String, List[Int]] = { 
    processInput(Source.fromFile(filename).getLines) 
    } 
    def processInput(lines: Iterator[String]): Map[String, List[Int]] = { 
    Try { 
     lines.foldLeft(Map[String, List[Int]]()) { (acc, line) => 

     val splitline = line.split(",").map(_.trim).toList 
     acc.updated(splitline.head, splitline.tail.map(_.toInt)) 
     } 
    }.getOrElse { 
     println("Sorry, an exception happened.") 
     Map() 
    } 
    } 





    // ******************************************************************************************************************* 
    // FUNCTIONS THAT INVOKE ACTION AND INTERACT WITH USER 
    // each of these functions accepts user input if required for an operation, 
    // invokes the relevant operation function and displays the results 

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

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

    //functionality to find the last tail element, the "Current" stock price 
    def findLast(list:List[Int]) = list.last 


    //Function to find the average 
    def average(list:List[Int]): Double = list.sum.toDouble/list.size 



    // ******************************************************************************************************************* 
    // OPERATION FUNCTIONS 
    // each of these performs the required operation on the data and returns 
    // the results to be displayed - does not interact with user 

    def currentPoints():Map[String,List[Int]] = { 
    // sort map by value in descending order - 
    ListMap(mapdata.toSeq.sortWith(_._1 < _._1):_*) 
    } 


    def allStockLevel(team: String): (String, List[Int]) = 
    (team, mapdata.get(team).getOrElse(List.empty)) 


    //Shows Highest Stock 
    def highestStockLevel(stock: String): (String, Int) = 
    (stock, mapdata.get(stock).map(_.max).getOrElse(0)) 

    //Shows the Lowest Stock 
    def lowestStockLevel(stock: String): (String, Int) = 
    (stock, mapdata.get(stock).map(_.min).getOrElse(0)) 


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

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



} 

回答

0

编辑

正如评论请求。

“例如‘SK1’,然后另一个值,‘SK2’,这将比较2所列出并返回的是更大的”

def largestList(a: String, b: String): Option[List[Int]] = { 
    (map.get(a), map.get(b)) match { 
    case (Some(alist), Some(blist)) => Some(List(alist, blist).maxBy(_.size)) 
    case _ => None 
    } 
} 

val map = Map("stock1" -> List(1, 2), "stock2" -> List(3, 4, 5)) 

scala> largestList("stock1", "stock2") 
res24: Option[List[Int]] = Some(List(3, 4, 5)) 

老答案

我认为,鉴于一个地图Map[String, List[Int]]你想要使用值(List [Int])中的值搜索地图

例如,如果你想获得密钥,值对包含两个数字1,2,然后做

map.filter { case (k, v) => v.exists(Set(1, 2)) } 

斯卡拉REPL

scala> val map = Map("stock1" -> List(1, 2), "stock2" -> List(3, 4, 5)) 
map: Map[String, List[Int]] = Map("stock1" -> List(1, 2), "stock2" -> List(3, 4, 5)) 

scala> map.filter { case (k, v) => v.exists(Set(3, 4))} 
res20: Map[String, List[Int]] = Map("stock2" -> List(3, 4, 5)) 
+0

这是一个有用的答案,但我需要的用户可以输入一个密钥值,比如“SK1”,然后另一个值,“SK2”这将比较2个列表并返回哪个更大 –

+0

@AndreQueen编辑了答案。请检查 – pamu