The list is being traversed twice. What you're essentially doing is first taking the Square
function and applying a reduce
on all the elements. Next the Sum
function will also apply a reduce
on all the elements.
A view turns the collection into a lazy one. Meaning if you have multiple transformations they will only be applied when they are needed. In this case, I don't think this has any impact on your solution, since you're applying functions that do calculations on whole collections (meaning they need to be evaluated to get the result). See this question for an answer on when to use views.
Traversing the second collection once isn't easy in this case. You have two functions that do a reduce
on the whole list, meaning each one needs a seperate accumulator and has a seperate result. If you want to only traverse your element list once, you need to change your logic a bit. Instead of defining operations on the whole list, you need to define operations on how to combine two elements. Here's what I came up with:
val functionListWithInitialValues = List(
((a: Int, b: Int) => a * b, 1), //This is a Tuple that defines how to combine two calculations and what the initial value is.
((a: Int, b: Int) => a + b, 0)
)
val results = list.foldLeft(functionListWithInitialValues) {
case (accumulators, next) => // foldLeft gives us the previous results
// (which is essentailly a Tuple(function, value)),
// and the next element, to combine with the previous result.
// Now let's go through our functions and apply the functions on the accumulator and the next element
accumulators.map {
case (function, previousResult) =>
(function, function(previousResult, next))
}
}
results.map { case (function, result) => println(result) }
This solution will only traverse your elements once, applying the combining function on the accumulator and the next element.