Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中,有没有更好或更实用的方法来比较地图中的两个值?_Scala_Functional Programming_Maps_Comparison - Fatal编程技术网

在Scala中,有没有更好或更实用的方法来比较地图中的两个值?

在Scala中,有没有更好或更实用的方法来比较地图中的两个值?,scala,functional-programming,maps,comparison,Scala,Functional Programming,Maps,Comparison,我有一些函数,允许用户比较地图中包含的两个团队。地图中包含的数据是从一个文本文件中读取的,该文件包含过去5个赛季的足球队及其计分信息。数据存储为Map[String,List[Int]]: Manchester United, 72, 86, 83, 90, 94 Manchester City, 80, 84, 91, 77, 88 Chelsea, 76, 85, 92, 87, 84 Arsenal, 70, 79, 81, 76, 83 Liverpool, 69, 77, 80, 73

我有一些函数,允许用户比较地图中包含的两个团队。地图中包含的数据是从一个文本文件中读取的,该文件包含过去5个赛季的足球队及其计分信息。数据存储为Map[String,List[Int]]:

Manchester United, 72, 86, 83, 90, 94
Manchester City, 80, 84, 91, 77, 88
Chelsea, 76, 85, 92, 87, 84
Arsenal, 70, 79, 81, 76, 83
Liverpool, 69, 77, 80, 73, 79
下面的功能允许用户输入两个团队的名称,并比较两个团队最近(最后)点数之间的差异

 val teamdata = readTextFile("teams.txt")

 //User presses 2 on keyboard, this invokes menuCompareTeams which invokes compareTeams
 def menuOptionTwo(): Boolean = {
   //2 - compare 2 teams selected by the user
   menuCompareTeams(compareTeams)
   true
 }

 //Function which displays the results of compareTeams
 def menuCompareTeams(f: (String, String) => ((String, Int), (String, Int), String)) = {
        val input = f(readLine("Enter first team to compare>"),
                      readLine("Enter second team to compare>"))
        println(s"""|Team 1: ${input._1._1} - Points: ${input._1._2}
                    |Team 2: ${input._2._1} - Points: ${input._2._2}
                    |${input._3}""".stripMargin)           
 }
   
 ///Function which compares the 2 teams - invoked by menuCompareTeams
 def compareTeams(team1: String, team2: String): ((String, Int), (String, Int), String) = {
   def lastPoints(list: List[Int]): Int = list match {
     case Nil => throw new Exception("Empty list")
     case h :: Nil => h
     case _ :: tail => lastPoints(tail)
   }

   val team1Points = teamdata.get(team1) match{
     case Some(p) => lastPoints(p)
     case None => 0
   }

   val team2Points = teamdata.get(team2) match{
     case Some(p) => lastPoints(p)
     case None => 0
   }

   val pointsComparison = if(team1Points > team2Points){
     "The team who finished higher is: " + team1 + ", their total points tally for last season was: " + team1Points + ". There was a difference of " + (team1Points-team2Points) + " points between the two teams."
   }
   else if(team1Points == team2Points){
     "The teams had equal points last season: " + (team1Points|team2Points)
   }
   else{
     "The team who finished higher is: " + team2 + ", their total points tally for last season was: " + team2Points + ". There was a difference of " + (team2Points-team1Points) + " points between the two teams."
   }

   ((team1, team1Points), (team2, team2Points), pointsComparison)
  
 }
例如,用户输入“曼联”和“曼彻斯特城”时的正确输出如下所示:

第一队:曼联-积分:94分

第二队:曼城-积分:88

排名靠前的球队是:曼联,他们上赛季的总积分是:94。两队相差6分

 val teamdata = readTextFile("teams.txt")

 //User presses 2 on keyboard, this invokes menuCompareTeams which invokes compareTeams
 def menuOptionTwo(): Boolean = {
   //2 - compare 2 teams selected by the user
   menuCompareTeams(compareTeams)
   true
 }

 //Function which displays the results of compareTeams
 def menuCompareTeams(f: (String, String) => ((String, Int), (String, Int), String)) = {
        val input = f(readLine("Enter first team to compare>"),
                      readLine("Enter second team to compare>"))
        println(s"""|Team 1: ${input._1._1} - Points: ${input._1._2}
                    |Team 2: ${input._2._1} - Points: ${input._2._2}
                    |${input._3}""".stripMargin)           
 }
   
 ///Function which compares the 2 teams - invoked by menuCompareTeams
 def compareTeams(team1: String, team2: String): ((String, Int), (String, Int), String) = {
   def lastPoints(list: List[Int]): Int = list match {
     case Nil => throw new Exception("Empty list")
     case h :: Nil => h
     case _ :: tail => lastPoints(tail)
   }

   val team1Points = teamdata.get(team1) match{
     case Some(p) => lastPoints(p)
     case None => 0
   }

   val team2Points = teamdata.get(team2) match{
     case Some(p) => lastPoints(p)
     case None => 0
   }

   val pointsComparison = if(team1Points > team2Points){
     "The team who finished higher is: " + team1 + ", their total points tally for last season was: " + team1Points + ". There was a difference of " + (team1Points-team2Points) + " points between the two teams."
   }
   else if(team1Points == team2Points){
     "The teams had equal points last season: " + (team1Points|team2Points)
   }
   else{
     "The team who finished higher is: " + team2 + ", their total points tally for last season was: " + team2Points + ". There was a difference of " + (team2Points-team1Points) + " points between the two teams."
   }

   ((team1, team1Points), (team2, team2Points), pointsComparison)
  
 }
有没有更好的或功能性的方法来做我目前正在做的两个团队的比较

编辑:我根据Alex的建议编辑了这个问题。

“更实用”

你确实有一个“副作用”,那就是为空列表抛出一个异常。如果这确实是一个例外情况,则
lastPoints
应返回一个。除此之外,您还可以保持引用的透明性,使用模式匹配,并使用递归函数,这样您就不会得到“更多的功能”

“更好”

您可以在
lastPoints
(假设不抛出异常)中使用,而不是编写自己的:

val lastPoints = (_ : List[Int]).lastOption
然后可按如下方式使用:

val getPoints = 
  (team : String) => teamdata.get(team)
                             .flatMap(lastPoints)
                             .getOrElse(0)

val team1Points = getPoints(team1)
val team2Points = getPoints(team2)

一般来说,我总是在尝试“滚动我自己的”之前寻找一种解决问题的收集方法。依靠
lastpoption
flatMap
getOrElse
可以减少bug的潜在位置。

包含多个问题的非常长的文本。我建议你把它分成几个问题。从基础开始:如何根据一个赛季的成绩比较两支球队更好。@AlexFruzenshtein谢谢你的反馈,我根据你的建议编辑了这个问题。