Open In App

Scala | aggregate() Function

Last Updated : 17 Apr, 2019
Improve
Improve
Like Article
Like
Save
Share
Report

The aggregate() function is utilized to combine outcomes. Initially, a sequence operation is applied as that is the first parameter of aggregate() function and then its followed by a combine operation which is utilized to combine the solutions generated by the sequence operation performed. This function can be enforced on all the collection data structures in Scala and can be practiced on Scala’s Mutable as well as Immutable collection data structures. It belongs to the TraversableOnce trait in Scala.
Syntax:

def aggregate[B](z: => B)(seqop: (B, A) => B, combop: (B, B) => B): B

Where,

  • B is the type of aggregated results, and z is the initial value for the aggregated result.
  • seqop is an operator for sequence operation and is utilized to figure out the sum of each of the elements of the stated collection and also enumerates the total number of elements in the collection.
  • combop is a combine operator which is utilized to combine the outcomes obtained by the parallel computation of the collection.
  • Parallel computation:
    Let, List = (2, 3, 4, 5, 6, 7, 8)
    Suppose, you have three threads of the list stated above where, let the first thread is (2, 3, 4), second thread is (5, 6) and the third thread is (7, 8).
    Now, lets perform parallel computation.
  • First thread = (2, 3, 4) = (2+3+4, 3) = (9, 3)
    // It is evaluated like below,
    // (sum of all the elements, total number of elements)
    
  • Second thread = (5, 6) = (5+6, 2) = (11, 2)
    
  • Third thread = (7, 8) = (7+8, 2) = (15, 2)
    

    Finally, after parallel computation, we have (9, 3), (11, 2), and (15, 2) and now this combine operator is applied to combine the outcomes of each thread i.e,

  • (9+11+15, 3+2+2) = (35, 7)

Now let’s see an example.
Example:




// Scala program of aggregate()
// function
  
// Creating an object
object GfG
{
  
    // Main method
    def main(args: Array[String]) 
    {
  
        // Creating a list of numbers
        val s = List(1, 2, 3, 4)
  
        // Applying aggregate function
        val r = s.par.aggregate((0, 0))((s, r) =>(s._1 + r, s._2 + 1), 
                                (s,r) => (s._1 + r._1, s._2 + r._2))
  
        // Displays summation of all the 
        // elements in the list and also
        // total number of elements
        println("(Sum of all the elements , total number of elements) = "+r)
    }
}


Output:

(Sum of all the elements, total number of elements) = (10, 4)

Here, par implies parallel which is utilized for the parallel computation of the list. we will discuss three parts in details.

aggregate(0, 0)

This is the first part where aggregate() function has two zeroes which are the initial values of the register s so, s._1 is at first zero which is utilized to figure out the sum of all the elements in the list and s._2 is also zero in the beginning which helps in enumerating the total number of elements in the list.

(s._1 + r, s._2 + 1)

This is the second part, it performs the sequence operation for the list stated above. The first part of this code evaluates the sum and the second part is for counting total elements. Now, lets see the evaluation step by step.
Here, List = (1, 2, 3, 4)

(s._1 + r, s._2 + 1) // (Initially, s._1 and s._2 = 0) 
= (0+1, 0+1) = (1, 1) // r is the initial value of the list
= (1+2, 1+1) = (3, 2)
= (3+3, 2+1) = (6, 3)
= (6+4, 3+1) = (10, 4)

This shows, how the evaluation is done exactly.

(s._1 + r._1, s._2 + r._2)

This is the last part, it is utilized in combine operation, as stated above in parallel computation. Suppose, during parallel computation of the list(1, 2, 3, 4), it is broken into two threads i.e, (1, 2) and (3, 4) then lets evaluate it step by step.
First thread :

(1, 2) = (1+2, 2) = (3, 2)

Second thread :

(3,  4) = (3+4, 2) = (7, 2)

Now, lets combine the two threads i.e, (3, 2) and (7, 2) using combine operator as stated above.

(s._1 + r._1, s._2 + r._2) // s._1 and s._2 = 0
= (0+3, 0+2) = (3, 2)       // r._1 = 3 and r._2 = 2
= (3+7, 2+2) = (10, 4)        // r._1 = 7 and r._2 = 2

Thus, this part works like this.

Lets see, one more example.
Example:




// Scala program of aggregate()
// function
  
// Creating an object
object GfG
{
  
    // Main method
    def main(args: Array[String]) 
    {
  
        // Creating a sequence of strings
        val seq = Seq("nidhi", "yes", "sonu", "Geeks")
  
        // Applying aggregate function
        val result = seq.par.aggregate(0)(_ + _.length, _ + _)
  
        // Displays total number of
        // letters used
        println("The total number of letters used are: "+result)
    }
}


Output:

The total number of letters used are: 17

Here, the initial value of the aggregate function is zero which is utilized to compute the total number of letters in the strings used here. The method length is used to enumerate the length of each string.
Let’s discuss the below code used in the above program in details.

(_ + _.length, _ + _)

Here, Seq = (“nidhi”, “yes”, “sonu”, “Geeks”)

Lets perform the sequence operation first.

 (0 + "nidhi".length ) // (0+5) = 5
 (0 + "yes".length)     // (0+3) = 3
 (0 + "sonu".length)       // (0+4) = 4
 (0 + "Geeks".length)        // (0+5) = 5

Therefore, we have (5), (3), (4), (5) from the sequence operation.
Now, lets perform combine operation.

(5+3) = 8 
(4+5) = 9
// Now lets combine it again
(8+9) = 17

Thus, total number of letters are 17.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads