在这种情况下,我可以避免变异吗?

问题描述 投票:1回答:3

我正在尝试迭代列表,然后对每个项目进行范围检查并相应地对分数进行cumalating。

挺直的。我觉得我是以更传统的方式做这件事并创造了很多“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)
scala
3个回答
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
投票

这是一种不同的方法,利用分数断点均匀间隔的事实:

val scores = Array.fill(5)(0)

list.foreach{ x =>
  val bucket = math.floor(x*4).toInt

  scores(bucket) += 1
}

这使用了可变的Array,但在这种特殊情况下可能是最有效的解决方案。


-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)
© www.soinside.com 2019 - 2024. All rights reserved.