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 nested value while comparing 2 objects - JavaScript
When working with complex nested objects, you often need to compare and group data from different states. This article demonstrates how to group array nested values while comparing two objects in JavaScript.
Problem Statement
Suppose we have a JSON object containing "before" and "after" states of device data:
const input = {
"before": {
"device": [
{
"id": "1234",
"price": "10",
"features": [
{
"name": "samsung",
"price": "10"
},
{
"name": "Apple",
"price": "20"
}
]
},
{
"id": "2154",
"price": "20",
"features": [
{
"name": "samsung",
"price": "30"
},
{
"name": "Moto",
"price": "40"
}
]
}
]
},
"after": {
"device": [
{
"id": "1234",
"price": "50",
"features": [
{
"name": "samsung",
"price": "20"
},
{
"name": "Lenovo",
"price": "30"
}
]
},
{
"id": "2158",
"price": "40",
"features": [
{
"name": "samsung",
"price": "30"
}
]
}
]
}
};
Our requirement is to group the id and its features into a single row, comparing the same id between the "before" and "after" objects. When a feature or device exists in only one state, it should show 0 for the missing state.
Solution Approach
We'll create a function that:
- Iterates through both "before" and "after" states
- Groups devices by their ID
- Merges features from both states
- Uses 0 as default value for missing data
Complete Implementation
const input = {
"before": {
"device": [
{
"id": "1234",
"price": "10",
"features": [
{
"name": "samsung",
"price": "10"
},
{
"name": "Apple",
"price": "20"
}
]
},
{
"id": "2154",
"price": "20",
"features": [
{
"name": "samsung",
"price": "30"
},
{
"name": "Moto",
"price": "40"
}
]
}
]
},
"after": {
"device": [
{
"id": "1234",
"price": "50",
"features": [
{
"name": "samsung",
"price": "20"
},
{
"name": "Lenovo",
"price": "30"
}
]
},
{
"id": "2158",
"price": "40",
"features": [
{
"name": "samsung",
"price": "30"
}
]
}
]
}
};
const formatJSON = data => {
const sub = Object.fromEntries(Object.keys(data).map(k => [k, 0]));
return Object.values(Object.entries(data).reduce((r, [col, { device }]) => {
device.forEach(({ id, price, features }) => {
r[id] = r[id] || [{ id, ...sub }];
r[id][0][col] = price;
features.forEach(({ name, price }) => {
let temp = r[id].find(q => q.name === name);
if (!temp) {
r[id].push(temp = { name, ...sub });
}
temp[col] = price;
});
});
return r;
}, {}));
};
console.log(formatJSON(input));
[
[
{ id: '1234', before: '10', after: '50' },
{ name: 'samsung', before: '10', after: '20' },
{ name: 'Apple', before: '20', after: 0 },
{ name: 'Lenovo', before: 0, after: '30' }
],
[
{ id: '2154', before: '20', after: 0 },
{ name: 'samsung', before: '30', after: 0 },
{ name: 'Moto', before: '40', after: 0 }
],
[
{ id: '2158', before: 0, after: '40' },
{ name: 'samsung', before: 0, after: '30' }
]
]
How It Works
The function works by:
-
Creating a template:
subobject initializes all columns with 0 - Processing each state: Iterates through "before" and "after" data
- Grouping by ID: Creates or updates device groups based on their ID
- Merging features: Adds features to the device group, creating new entries for unseen features
- Filling gaps: Missing values default to 0
Key Features
- Handles devices that exist in only one state
- Merges features from both states intelligently
- Maintains data structure consistency
- Uses 0 for missing values to enable easy comparison
Conclusion
This approach effectively groups and compares nested array data from two object states. It's particularly useful for tracking changes in complex data structures like device configurations or feature comparisons.
