如何在函数样式中添加列表中选择行的值?

Twi*_*ton 4 functional-programming scala sum list

我以命令式的方式解决了我的问题,但它看起来非常难看.我怎样才能做得更好(更优雅,更简洁,更实用 - 最后是Scala).应跳过与前一行具有相同值但具有不同字母的行,应添加行的所有其他值.

val row1 = new Row(20, "A", true)    // add value  
val row2 = new Row(30, "A", true)    // add value  
val row3 = new Row(40, "A", true)    // add value  
val row4 = new Row(40, "B", true)    // same value as the previous element & different letter -> skip row  
val row5 = new Row(60, "B", true)    // add value  
val row6 = new Row(70, "B", true)    // add value  
val row7 = new Row(70, "B", true)    // same value as the previous element, but the same letter -> add value  

val rows = List(row1, row2, row3, row4, row5, row6, row7)  

var previousLetter = " "    
var previousValue  = 0.00  
var countSkip = 0  

for (row <- rows) {  
  if (row.value == previousValue && row.letter != previousLetter) {  
      row.relevant = false  
      countSkip += 1  
  }  
  previousLetter = row.letter  
  previousValue  = row.value  
}  

// get sum  
val sumValue = rows.filter(_.relevant == true).map(_.value) reduceLeftOption(_ + _)  
val sum = sumValue match {  
    case Some(d) => d  
    case None => 0.00  
}  

assert(sum == 290)  
assert(countSkip == 1) 
Run Code Online (Sandbox Code Playgroud)

提前致谢

Twistleton

Lan*_*dei 9

(rows.head :: rows).sliding(2).collect{ 
     case List(Row(v1,c1), Row(v2,c2)) if ! (v1 == v2 && c1 != c2) => v2 }.sum
Run Code Online (Sandbox Code Playgroud)


Rex*_*err 6

我认为当Row是一个案例类(删除布尔值)时,最短(防弹)的解决方案是

(for ((Row(v1,c1), Row(v2,c2)) <- (rows zip rows.take(1) ::: rows) if (v1 != v2 || c1 == c2)) yield v1).sum
Run Code Online (Sandbox Code Playgroud)

其他一些解决方案不处理list-is-empty的情况,但这很大程度上是因为sliding如果列表太短,它会返回部分列表.对我来说更清楚(也是防弹)是:

(rows zip rows.take(1) ::: rows).collect{
  case (Row(v1,c1), Row(v2,c2)) if (v1 != v2 || c1 == c2) => v1
}.sum
Run Code Online (Sandbox Code Playgroud)

(如果将它保持在一行,则只有两个字符).如果你还需要跳过这个号码,

val indicated = (rows zip rows.take(1) ::: rows).collect {
  case (Row(v1,c1), Row(v2,c2)) => (v1, v1 != v2 || c1 == c2)
}
val countSkip = indicated.filterNot(_._2).length
val sum = indicated.filter(_._2).map(_._1).sum
Run Code Online (Sandbox Code Playgroud)