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
Join two objects by key in JavaScript
When working with related data structures, you often need to join objects from different arrays based on matching keys. This is common when dealing with parent-child relationships or normalized data.
Suppose we have two arrays - one containing child objects and another containing parent objects:
const child = [{
id: 1,
name: 'somename',
parent: {
id: 2
},
},
{
id: 2,
name: 'some child name',
parent: {
id: 4
}
}];
const parent = [{
id: 1,
parentName: 'The first',
child: {}
},
{
id: 2,
parentName: 'The second',
child: {}
},
{
id: 3,
parentName: 'The third',
child: {}
},
{
id: 4,
parentName: 'The fourth',
child: {}
}];
Our goal is to merge child objects into their corresponding parent objects based on the relationship defined by the parent ID.
Method 1: Using Nested Loops
The straightforward approach uses nested loops to find matching relationships:
const child = [{
id: 1,
name: 'somename',
parent: {
id: 2
},
},
{
id: 2,
name: 'some child name',
parent: {
id: 4
}
}];
const parent = [{
id: 1,
parentName: 'The first',
child: {}
},
{
id: 2,
parentName: 'The second',
child: {}
},
{
id: 3,
parentName: 'The third',
child: {}
},
{
id: 4,
parentName: 'The fourth',
child: {}
}];
const combineParentChild = (parent, child) => {
const combined = [];
for (let i = 0; i < parent.length; i++) {
for (let j = 0; j < child.length; j++) {
if (child[j].parent.id === parent[i].id) {
parent[i].child.id = child[j].id;
parent[i].child.name = child[j].name;
break;
};
};
combined.push(parent[i])
};
return combined;
};
console.log(combineParentChild(parent, child));
[
{ id: 1, parentName: 'The first', child: {} },
{
id: 2,
parentName: 'The second',
child: { id: 1, name: 'somename' }
},
{ id: 3, parentName: 'The third', child: {} },
{
id: 4,
parentName: 'The fourth',
child: { id: 2, name: 'some child name' }
}
]
Method 2: Using Map for Better Performance
For larger datasets, using a Map provides better performance by eliminating the inner loop:
const combineWithMap = (parent, child) => {
// Create a map of parent ID to child object
const childMap = new Map();
child.forEach(childObj => {
childMap.set(childObj.parent.id, {
id: childObj.id,
name: childObj.name
});
});
// Merge child data into parent objects
return parent.map(parentObj => ({
...parentObj,
child: childMap.get(parentObj.id) || {}
}));
};
// Test with same data
const result = combineWithMap(parent, child);
console.log(result);
[
{ id: 1, parentName: 'The first', child: {} },
{
id: 2,
parentName: 'The second',
child: { id: 1, name: 'somename' }
},
{ id: 3, parentName: 'The third', child: {} },
{
id: 4,
parentName: 'The fourth',
child: { id: 2, name: 'some child name' }
}
]
Comparison
| Method | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| Nested Loops | O(n × m) | O(1) | Small datasets |
| Map-based | O(n + m) | O(m) | Large datasets |
Key Points
- The nested loop approach modifies the original parent array
- The Map approach creates a new array without modifying the original
- Always handle cases where no matching relationship exists
- Consider using spread operator (...) to avoid mutating original objects
Conclusion
Joining objects by key is essential for combining related data. Use nested loops for simplicity with small datasets, or Map-based approaches for better performance with larger data structures.
