2016-11-12 96 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