Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do add values of selective rows from a list in an functional style?

I solved my problem in an imperative style, but it looks very ugly. How can I make it better (more elegant, more concise, more functional - finally its Scala). Rows with the same values as the previous row, but with a different letter should be skipped, all other values of the rows should be added.

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) 

Thanks in advance

Twistleton

like image 638
Twistleton Avatar asked Nov 30 '22 17:11

Twistleton


1 Answers

(rows.head :: rows).sliding(2).collect{ 
     case List(Row(v1,c1), Row(v2,c2)) if ! (v1 == v2 && c1 != c2) => v2 }.sum
like image 182
Landei Avatar answered Dec 05 '22 04:12

Landei