How to group array by date in Javascript – Fast Tips

Valerio Barbera
group-array-by-date-javascript

I use this technique to group the bug fixes array by date in the Inspector UI, and I thought it could be a good code snippet idea for other developers. I also wrote an implementation for Vuejs and a more detailed implementation that supports filters.

I needed to implement this solution to make a list of items history easy to scroll for users.

Use native groupBy function

const items = [
    {"created_at": "2023-06-01", "value": 10},
    {"created_at": "2023-06-02", "value": 20},
    {"created_at": "2023-06-01", "value": 30},
    {"created_at": "2023-06-03", "value": 40},
    {"created_at": "2023-06-02", "value": 50},
];

let groups = Object.groupBy(items, item => moment(item.created_at).format('YYYY-MM-DD'));

I decided to use moment as a date library because the standard javascript Date object doesn’t provide an easy way to format dates. Thanks to the moment’s format method you could customize the grouping string by the month or the year, simply by changing the format string: ‘YYYY-MM’ for month, or ‘YYYY’ for year.

Things to know

The native groupBy() function returns a null-prototype object. This means that the resulting object does not have the native object methods you could expect like hasOwnProperty().

If you call the method it will result in a “not a function error”:

// TypeError: groups.hasOwnProperty is not a function
console.log(groups.hasOwnProperty("2023-06-01"));

To overcome this limitation you can implement the grouping strategy by yourself using the reduce function and get a fully functional object in return.

Grouping with the reduce function

If you want more control on the new object creation process you can implement the raw strategy using the reduce function. It allows you to progressively create a new object where each date becomes a key of the resulting object, with the corresponding element as its value.

let groups = items.reduce((group, item) => {
    let date = moment(item.created_at).format('YYYY-MM-DD');
		
    if (!group[date]) {
        group[date] = [];
    }
		
    group[date].push(item);
		
    return group;
}, {}); // <-- Start with an empty object

Support Filtering

You can also introduce a filter function to filter the elements of the resulting object before grouping.

let groups = items.filter(item => {
    // Filtering before grouping
    return item.value > 20;
}).reduce((group, item) => {
    let date = moment(item.created_at).format('YYYY-MM-DD');
		
    if (!group[date]) {
        group[date] = [];
    }
		
    group[date].push(item);
    
    return group;
}, {}); // <-- Start with an empty object

Inside the callback function of filter(), we specify the filter condition. In this example, we keep only the elements where the ‘value’ field is greater than a threshold. You can modify this condition based on your specific use case.

Use it inside a Vuejs component

To preserve the reactivity of the data manipulation statements I use a computed property, so it will change if the underlying collection changes. I implement only the data structure iteration on the template side.

Here is the component structure:

<template>
    <div v-for="(group, date) in groups">
        <h4>{{date}}</h4>
		
        <ul>
            <li v-for="item in group">{{item.value}}</li>
        </ul>
		
        </br>
    </div>
</template>

<script>
import moment from "moment";

export default {
    data() {
        return {
            threshold: 0,
            items: [
                {"created_at": "2023-06-01", "value": 10},
                {"created_at": "2023-06-02", "value": 20},
                {"created_at": "2023-06-01", "value": 30},
                {"created_at": "2023-06-03", "value": 40},
                {"created_at": "2023-06-02", "value": 50},
            ],
        }
    },

    computed: {
        groups() {
            return this.items.filter(item => {
                return item.value > this.threshold;
            }).reduce((group, item) => {
                let date = moment(item.created_at).format('YYYY-MM-DD');
                if (!group[date]) {
                    group[date] = [];
                }
                group[date].push(item);
                return group;
            }, {});
        }
    },
}
</script>

You can follow me on Linkedin or X. I post about building my SaaS business.

Monitor your application for free

Inspector is a Code Execution Monitoring tool specifically designed for software developers. You don’t need to install anything in the infrastructure, just install the client library based on the technology you use.

Inspector is super easy to use and require zero configuration.

If you are looking for HTTP monitoring, query insights, and the ability to forward alerts and notifications into your messaging environment try Inspector for free. Register your account.

Or learn more on the website: https://inspector.dev

Inspector Code Execution Monitoring

Related Posts

Neuron AI Now Supports ZAI — The GLM Series Is Worth Your Attention

There’s a pattern I’ve noticed over the past year while working on Neuron AI: the decisions that matter most are rarely about chasing trends. They’re about quietly recognizing something that works, testing it seriously, and integrating it so that other developers can benefit without having to do that work themselves. That’s the honest story behind

Maestro: A Customizable CLI Agent Built Entirely in PHP

For a long time, the implicit message from the AI tooling industry has been: if you want to build agents, learn Python. The frameworks, the tutorials, the conference talks, all pointed in the same direction. PHP developers who wanted to experiment with autonomous systems had two options: switch stacks or stitch something together from raw

Neuron v3 is Here! 🚀 Agentic Workflows in PHP

Exactly one year ago, we shared the first public lines of Neuron AI with the world. Six months ago, we stood at the crossroads of V2, refining our vision. Today, we arrive at Version 3 as the first agentic framework of the PHP world. I’m aware that a major release every six months is a