I'm very new to Scala so excuse that this is probably a simple misunderstanding of the language. I have a function:
def compareNextElemToMinElem(lst: List[Int]) = {
val max = lst.foldLeft((lst(0),lst(0),0)) { (minSoFar:Int, x:Int, maxDiff:Int) =>
if (x < minSoFar) (minSoFar, x, maxDiff)
if (x - minSoFar > maxDiff) (minSoFar, x, x - minSoFar)
else (minSoFar, x, x - minSoFar)
}
max._3
}
Basically it should go one element at a time and track the biggest difference in elements so far. By calling max._3
I hope to return the final maxDiff
from the foldLeft call. I'm getting an error:
type mismatch;
found : (Int, Int, Int) => (Int, Int, Int)
required: ((Int, Int, Int), Int) => (Int, Int, Int)
val max = lst.foldLeft((lst(0),lst(0),0)) { (minSoFar:Int, x:Int, maxDiff:Int) =>
Additionally, I have to put (minSoFar:Int, x:Int, maxDiff:Int)
instead of (minSoFar, x, maxDiff)
to avoid a missing parameter type
error. Why is that?
Both the syntax and logic seemed not entirely correct, here is a possible fix:
def compareNextElemToMinElem(lst: List[Int]) = {
lst.foldLeft((lst.head, lst.head)) { case ((minSoFar, maxDiff), x) =>
if (x < minSoFar) (x, maxDiff)
else if (x - minSoFar > maxDiff) (minSoFar, x - minSoFar)
else (minSoFar, maxDiff)
}._2
}
println(compareNextElemToMinElem(List(1,-2,3,-1,4,8,2)))
prints
10
which is 8 - (-2)
.
Brief explanation:
minSoFar
and maxDiff
, not three.x
must come from the list,
not from the "accumulator" that is passed from previous stepfold
, in general, takes a function that takes two arguments:
list.fold(accumulator0){ (acc, currentValue) => nextAcc }
Since here your accumulator acc
is itself a tuple, you have to pattern match on the first component with case
, so:
list.fold((a0, b0)) { case ((ai, bi), x) => (nextAi, nextBi) }
I didn't understand your if-else
logic, no guarantee that it does what you intended.