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
Selected Reading
Group a JavaScript Array
Grouping JavaScript arrays by a specific property is a common requirement when working with complex data structures. In this tutorial, we'll learn how to group array elements by the tableName property and restructure the data.
Problem Statement
Suppose we have a JavaScript array with objects containing table data:
const data = [
{
"dataId": "1",
"tableName": "table1",
"column": "firstHeader",
"rows": ["a", "b", "c"]
},
{
"dataId": "2",
"tableName": "table1",
"column": "secondHeader",
"rows": ["d", "e", "f"]
},
{
"dataId": "3",
"tableName": "table2",
"column": "aNewFirstHeader",
"rows": [1, 2, 3]
}
];
console.log("Original data:");
console.log(JSON.stringify(data, null, 2));
Original data:
[
{
"dataId": "1",
"tableName": "table1",
"column": "firstHeader",
"rows": [
"a",
"b",
"c"
]
},
{
"dataId": "2",
"tableName": "table1",
"column": "secondHeader",
"rows": [
"d",
"e",
"f"
]
},
{
"dataId": "3",
"tableName": "table2",
"column": "aNewFirstHeader",
"rows": [
1,
2,
3
]
}
]
Expected Output
We need to group objects by tableName and combine their columns and rows:
const expectedOutput = [
{
"tableName": "table1",
"column": ["firstHeader", "secondHeader"],
"rows": [["a", "b", "c"], ["d", "e", "f"]]
},
{
"tableName": "table2",
"column": ["aNewFirstHeader"],
"rows": [[1, 2, 3]]
}
];
Solution Using reduce() and Map
Here's an efficient solution using reduce() with a Map for grouping:
const arr = [
{
"dataId": "1",
"tableName": "table1",
"column": "firstHeader",
"rows": ["val", "b", "c"]
},
{
"dataId": "2",
"tableName": "table1",
"column": "secondHeader",
"rows": ["d", "e", "f"]
},
{
"dataId": "3",
"tableName": "table2",
"column": "aNewFirstHeader",
"rows": [1, 2, 3]
}
];
const groupArray = (arr = []) => {
const res = arr.reduce((obj => (acc, val) => {
let item = obj.get(val.tableName);
if (!item) {
item = {
tableName: val.tableName,
column: [],
rows: []
};
obj.set(val.tableName, item);
acc.push(item);
}
item.column.push(val.column);
item.rows.push(val.rows);
return acc;
})(new Map), []);
return res;
};
console.log("Grouped result:");
console.log(JSON.stringify(groupArray(arr), null, 2));
Grouped result:
[
{
"tableName": "table1",
"column": [
"firstHeader",
"secondHeader"
],
"rows": [
[
"val",
"b",
"c"
],
[
"d",
"e",
"f"
]
]
},
{
"tableName": "table2",
"column": [
"aNewFirstHeader"
],
"rows": [
[
1,
2,
3
]
]
}
]
How It Works
The solution uses a closure pattern with reduce():
- Creates a
Mapto track unique table names - For each array element, checks if the table name exists in the map
- If not found, creates a new grouped object and adds it to both the map and result array
- Appends the current column and rows to the existing grouped object
Alternative Approach Using forEach
const groupArraySimple = (arr) => {
const grouped = {};
const result = [];
arr.forEach(item => {
if (!grouped[item.tableName]) {
grouped[item.tableName] = {
tableName: item.tableName,
column: [],
rows: []
};
result.push(grouped[item.tableName]);
}
grouped[item.tableName].column.push(item.column);
grouped[item.tableName].rows.push(item.rows);
});
return result;
};
console.log("Alternative approach:");
console.log(JSON.stringify(groupArraySimple(arr), null, 2));
Alternative approach:
[
{
"tableName": "table1",
"column": [
"firstHeader",
"secondHeader"
],
"rows": [
[
"val",
"b",
"c"
],
[
"d",
"e",
"f"
]
]
},
{
"tableName": "table2",
"column": [
"aNewFirstHeader"
],
"rows": [
[
1,
2,
3
]
]
}
]
Conclusion
Grouping arrays by properties is efficiently achieved using reduce() with Map or a simple object lookup. The reduce() approach is more functional, while forEach offers better readability for beginners.
Advertisements
