我正在尝试迭代一个列表,然后对每个项目进行范围检查并相应地累积分数。
挺直的。我觉得我正在以更传统的方式执行此操作,并创建了许多“ var”变量。
是否存在一种有效的功能/不变方式来实现此行为?
var score_1 = 0
var score_2 = 0
var score_3 = 0
var score_4 = 0
var score_5 = 0
val list = List(1,1,1,0.8,0.75,0.7,0.7,0.5,0.4,0.25,0.2,0.15,0.1)
list.foreach( i => {
i.toDouble match {
case x if( x == 1.0 ) => score_1 += 1
case x if( x >= 0.75 && x < 1 ) => score_2 += 1
case x if( x >= 0.50 && x < 0.75) => score_3 += 1
case x if( x >= 0.25 && x < 0.50) => score_4 += 1
case x if( x >= 0 && x < 0.25 ) => score_5 += 1
case _ =>
}
})
println(score_1,score_2,score_3,score_4,score_5)
答案 0 :(得分:2)
是的,您可以使用foldLeft
来实现不变性,
case class Score(score1: Int,
score2: Int,
score3: Int,
score4: Int,
score5: Int,
score6: Int,
score7: Int,
score8: Int)
object Score {
def empty = new Score(0, 0, 0, 0, 0, 0, 0, 0)
}
val myScore = list.foldLeft(Score.empty) {
case (score, 1.0) => score.copy(score1 = score.score1 + 1)
case (score, x) if x > 0.75 && x < 1 => score.copy(score2 = score.score2 + 1)
case (score, 0.75) => score.copy(score3 = score.score3 + 1)
case (score, x) if x > 0.50 && x < 0.75 => score.copy(score4 = score.score4 + 1)
case (score, 0.50) => score.copy(score5 = score.score5 + 1)
case (score, x) if x > 0.25 && x < 0.50 => score.copy(score6 = score.score6 + 1)
case (score, 0.25) => score.copy(score7 = score.score7 + 1)
case (score, x) if x >= 0 && x < 0.25 => score.copy(score8 = score.score8 + 1)
case (score, _) => score
}
println(myScore) // Score(3,1,1,2,1,1,1,3)
答案 1 :(得分:1)
这是一种不同的方法,它利用分数断点平均分布这一事实:
val scores = Array.fill(5)(0)
list.foreach{ x =>
val bucket = math.floor(x*4).toInt
scores(bucket) += 1
}
这使用了可变的Array
,但在这种情况下可能是最有效的解决方案。
答案 2 :(得分:-1)
感谢@Prayagupd ..好的答案。这很有帮助。同时,我正在尝试另一种实现此目标的方法。请随时让我知道您的想法。
val scoreMap = list.map( i => {
i.toDouble match {
case x if( x == 1.0 ) => (1,1)
case x if( x >= 0.75 && x < 1 ) => (2,1)
case x if( x >= 0.50 && x < 0.75) => (3,1)
case x if( x >= 0.25 && x < 0.50) => (4,1)
case x if( x >= 0 && x < 0.25 ) => (5,1)
case _ => (0,0)
}
}).groupBy(_._1).mapValues( _.map(_._2).sum ).toMap
println(TreeMap(scoreMap.toSeq:_*)) //(1 -> 3, 2 -> 2, 3 -> 3, 4 -> 2, 5 -> 3)