6

For example, suppose I wish to read in fat, carbs and protein and wish to print the running total of each variable. An imperative style would look like the following:

var totalFat = 0.0
var totalCarbs = 0.0
var totalProtein = 0.0
var lineNumber = 0

for (lineData <- allData) {
    totalFat += lineData...
    totalCarbs += lineData...
    totalProtein += lineData...
    lineNumber += 1

    printCSV(lineNumber, totalFat, totalCarbs, totalProtein)

}

How would I write the above using only vals?

4 Answers 4

13

Use scanLeft.

val zs = allData.scanLeft((0, 0.0, 0.0, 0.0)) {  case(r, c) =>
  val lineNr = r._1 + 1
  val fat = r._2 + c...
  val carbs = r._3 + c...
  val protein = r._4 + c...
  (lineNr, fat, carbs, protein)
}

zs foreach Function.tupled(printCSV)
Sign up to request clarification or add additional context in comments.

Comments

3

Recursion. Pass the sums from previous row to a function that will add them to values from current row, print them to CSV and pass them to itself...

Comments

2

You can transform your data with map and get the total result with sum:

val total = allData map { ... } sum

With scanLeft you get the particular sums of each step:

val steps = allData.scanLeft(0) { case (sum,lineData) => sum+lineData}
val result = steps.last

If you want to create several new values in one iteration step I would prefer a class which hold the values:

case class X(i: Int, str: String)
object X {
  def empty = X(0, "")
}
(1 to 10).scanLeft(X.empty) { case (sum, data) => X(sum.i+data, sum.str+data) }

Comments

0

It's just a jump to the left,
and then a fold to the right /:

class Data (val a: Int, val b: Int, val c: Int) 
val list = List (new Data (3, 4, 5), new Data (4, 2, 3), 
                 new Data (0, 6, 2), new Data (2, 4, 8)) 
val res = (new Data (0, 0, 0) /: list) 
  ((acc, x) => new Data (acc.a + x.a, acc.b + x.b, acc.c + x.c))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.