Grouping array values in JavaScript

Suppose we have an array of objects containing some years and weeks data like this:

const arr = [
    {year: 2017, week: 45},
    {year: 2017, week: 46},
    {year: 2017, week: 47},
    {year: 2017, week: 48},
    {year: 2017, week: 50},
    {year: 2017, week: 52},
    {year: 2018, week: 1},
    {year: 2018, week: 2},
    {year: 2018, week: 5}
];

We are required to write a JavaScript function that takes in one such array. The function should return a new array where all the objects that have common value for the "year" property are grouped into a separate object.

Therefore, the output object for the above array should look like:

[
    { 
        "2017": [
            { "value": 45 },
            { "value": 46 },
            { "value": 47 },
            { "value": 48 },
            { "value": 50 },
            { "value": 52 }
        ]
    },
    { 
        "2018": [
            { "value": 1 },
            { "value": 2 },
            { "value": 5 }
        ]
    }
]

Method 1: Using forEach and Map

This approach uses a temporary map to track years and builds the result array as we process each item:

const arr = [
    {year: 2017, week: 45},
    {year: 2017, week: 46},
    {year: 2017, week: 47},
    {year: 2017, week: 48},
    {year: 2017, week: 50},
    {year: 2017, week: 52},
    {year: 2018, week: 1},
    {year: 2018, week: 2},
    {year: 2018, week: 5}
];

const groupByYear = arr => {
    const res = [];
    const map = {};
    
    arr.forEach(item => {
        const temp = {};
        if (!map[item.year]) {
            map[item.year] = [];
            temp[item.year] = map[item.year];
            res.push(temp);
        }
        map[item.year].push({ value: item.week });
    });
    
    return res;
};

console.log(JSON.stringify(groupByYear(arr), null, 2));
[
  {
    "2017": [
      { "value": 45 },
      { "value": 46 },
      { "value": 47 },
      { "value": 48 },
      { "value": 50 },
      { "value": 52 }
    ]
  },
  {
    "2018": [
      { "value": 1 },
      { "value": 2 },
      { "value": 5 }
    ]
  }
]

Method 2: Using reduce for Cleaner Code

The reduce method provides a more functional approach to grouping:

const arr = [
    {year: 2017, week: 45},
    {year: 2017, week: 46},
    {year: 2018, week: 1},
    {year: 2018, week: 2}
];

const groupByYearReduce = arr => {
    const grouped = arr.reduce((acc, item) => {
        if (!acc[item.year]) {
            acc[item.year] = [];
        }
        acc[item.year].push({ value: item.week });
        return acc;
    }, {});
    
    // Convert to array format
    return Object.keys(grouped).map(year => ({
        [year]: grouped[year]
    }));
};

console.log(JSON.stringify(groupByYearReduce(arr), null, 2));
[
  {
    "2017": [
      { "value": 45 },
      { "value": 46 }
    ]
  },
  {
    "2018": [
      { "value": 1 },
      { "value": 2 }
    ]
  }
]

How It Works

Both methods follow these steps:

  • Track groups: Use an object/map to store arrays for each year
  • Process items: For each item, check if the year exists in our tracker
  • Create groups: If new year, create a new group in the result array
  • Add values: Push week values as objects with "value" property

Comparison

Method Readability Performance Best For
forEach + Map Moderate Good Step-by-step processing
reduce High Good Functional programming style

Conclusion

Both approaches effectively group array objects by a common property. The reduce method offers cleaner, more functional code, while forEach provides explicit step-by-step control over the grouping process.

Updated on: 2026-03-15T23:19:00+05:30

519 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements