Write your own groupBy and aggregate/fold function in Javascript- Part 2

KF
5 min readDec 25, 2019

--

This article is in the continuation of my last article where I created our own groupBy function written in typescript. I will expand that some functionality of grouping along with folding the grouped values based on some function. We will write our fold function in a declarative way. Let’s look at the sql query to fold some grouped values:

In the above SQL query AVG is an aggregate/fold function which works upon the grouped values and calculates an aggregate value that represents the whole group. In this query, AVG calculates the average of marks of all students grouped by subject.

Let’s recap our older groupBy function first and then we’ll expand it:

Now we’ll write our own declarative style fold function such that it works upon the grouped values in the same manner as the SQL query above does.

Description of the function

Our ‘groupThenFold’ accepts three parameters ( I have written the curried version for the same reason as groupBy function ).

First parameter is the ‘groupFn’. This function will accept an input of type ‘V’ ( which is the type of data in collection) and returns a value of type ‘K’ which will become the key to our map.
groupFn: (x: V) => K

Second parameter is the ‘aggFn’. This function will accept an array of type ‘V’ ( which is type of data in grouped collection ) and returns an aggregated value of a new type ‘T’. This function does the same work as the aggregate functions of SQL.
aggFn: (x: V[]) => T

Third parameter is the collection on which we want to apply grouping.
collection: V[]

The return type of ‘groupThenFold’ function is a map. Compared this return type with the return type of ‘groupBy’ function above.
Map<K, T>

Types specified in the function declaration ensures that all the types are aligned while using the function. If you have focused on the function declaration of both the functions, you might have noticed that the collection of data that is to be processed is always the last argument in the curried version. That is because, we can have partial functions with group function and aggregate function already applied to it. Then that partial function can be combined with the other partial function that work upon the collection of data. To know more about composition, follow this article on composition.

Usage

Let’s assume we have the data in following format:

Our group function is same as in the last article based on the subject:

Now Let’s write our aggregate function first:

You can check if the type of our aggregate function align with function definition of groupThenFold function.

The result of groupedAndFoldData is

The collection is grouped by subject and then each group values are folded by our average function.
So we implemented a full fledged declarative function to group and fold a collection along with type safety and benefits of function composition. In fact, we have created a short and declarative query engine to process data in SQL way. These group and fold functions along with javascript array’s map, filter and reduce function can make a reasonable query engine for your web application.

Bonus

If you have ever come across functional programming, you might have guessed that our ‘groupThenFold’ function can work as ‘groupBy’ function as well.
We can have an indentity function which takes an input of any type and return the same value without doing anything.

You may think that what purpose in the great universe of coding this identity function serves. You can think of this function as the identity value of function composition. When identity function is composed with any function, it does nothing to that function. Again confusing!
You may need to go back and think of what 0(zero) does when added to any number. In fact, it does nothing to that number. Zero is additive identity for numbers. The same way, our identity function is composition identity for any function in the godly realm of functions.

0 + 0 = 0
compose(identity, identity) = identity(identity) = identity

0 + x = x + 0 = x
compose(identity, fn) = compose(fn, identity) = identity

The above groupByFn is similar to groupBy function. You can look it this way; identity is an aggregate function which doesn’t aggregate at all and returns the same value. Again confusing! The analogy is similar to zero added to any number doesn’t add any thing at all and returns the same number.
Identities have their own realms of use cases in algebra especially in various branches of abstract algebra like group theory, category theory, graph theory etc.

Previous Post: GroupBy Function

--

--

KF

Interested in beginnings rather than end, gives values to past not to repent but to analyze, learning history of philosophy and philosophy of mathematics.