Search code examples
scalasub-arrayfoldleft

Is it possible to update a variable in foldLeft function based on a condition?


I am trying to write scala code which gives maximum sum from contiguous sub-array from the given array. For example, val arr= Array(-2, -3, 4, -1, -2, 1, 5, -3). In this array I need to get maximum contiguous sub-array sum i.e 4+(-1)+(-2)+(1)+5 = 7. I wrote following code for getting this result.

scala> arr.foldLeft(0) { (currsum,newnum) => if((currsum+newnum)<0) 0 else { if(currsum<(currsum+newnum)) (currsum+newnum) else currsum }}
res5: Int = 10

but deviated from actual result as I am unable to update the maximum_so_farvalue as the counting/summation goes on. Since I have used foldLeft to do this functionality, is there any possibility to update the maximum_so_farvariable only when sum of contiguous sub array elements is greater than previous max_sum?

reference link for better understanding of scenario


Solution

  • Well, obviously you have to propagate two values along your input data for this computation, just as you would need to do in the imperative case:

    arr.foldLeft((0,0)){
      case ((maxSum, curSum), value) => {
        val newSum = Math.max(0, curSum + value)
        (Math.max(maxSum, newSum), newSum)  
      }
    }._1
    

    An other way would be to compute the intermediate results (lazily if you want) and then select the maximum:

    arr.toIterator.scanLeft(0){
      case (curSum, value) =>
        Math.max(0, curSum + value)
    }.max