在Scala中,有没有更好或更实用的方法来比较地图中的两个值?
我有一些函数,允许用户比较地图中包含的两个团队。地图中包含的数据是从一个文本文件中读取的,该文件包含过去5个赛季的足球队及其计分信息。数据存储为Map[String,List[Int]]:在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
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谢谢你的反馈,我根据你的建议编辑了这个问题。