Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
