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

KF
4 min readDec 24, 2019

--

How often do we need to group a collection of data based on some prop or group function? This is a very widely used use case in today’s front end web apps. But unfortunately, there is no language implementation of groupBy in javascript specification. So many new javascript developers ( and even experienced ) incorporate some third party library like lodash or underscore to get the grouping task done. I don’t ask anyone not to use these libraries. At the end these are well tested libraries for utility function. But sometimes these libraries add the jungle along with the banana we want.

In SQL, we have the declarative approach to group result based on some column value:

Do you know why SQL is still popular after around 40 years of the first inception of it? The reason is ‘Declarative approach’. We will develop the same declarative way of grouping a collection. We will also introduce the type of the function in typescript so that we can also get benefit of the compile time checking and type inference.

Let’s first write our heroic function and then dive into the details:

If you want to copy the code, below is the text version:

// groupBy:: (V -> K) -> (Array<V>) -> Map<K, V[]>
const groupBy = <K, V>(groupFn: (x: V) => K) => (collection: V[]) => {
const cMap = new Map<K, V[]>();
for (const v of collection) {
const key = groupFn(v); //get the key from the groupFn
// check if key exists else intialize the value with blank array
const value = (cMap.get(key) || []);
value.push(v);
cMap.set(key, value);
}
return cMap;
};

Description of the function

Our ‘groupBy’ function accepts two parameters( I have written the curried version of it. Both parameters can be combined. But the curried version makes it easy to compose it with other functions ).

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 collection on which we want to apply grouping.
collection: V[]

The return type of ‘groupBy’ function is a map.
Map<K, V[]>

Types specified in the function declaration ensures that all the types are aligned while using the function.

Usage

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

Now we want to group the students based on subject.

The first thing we need our group function which can be defined as below:

Please keep in mind the type of our group function:
groupFn: (x: V) => K
where K becomes the key type of our map.
We can do any kind of processing in group function. It’s not mandatory to return a property of the object. Our group function can be as below:

So our group function can do any processing until it is aligned with types and pure(Always remember this pure part).

Now we group our data using our group function as follows:

The result of grouped data is :

The collection is grouped by ‘subject’ as specified in the grouping function.

So we implemented a pure declarative and pure function to group a collection of data along with type safety.

This approach can even be further extended to group data at multiple nested levels. We can even write our own query engine by combining this groupBy function with an aggregate function!

Next Post: Aggregate 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.