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
Transform tree from DB format to JSON format in JavaScript
When working with database records, data is often stored in a flat structure with parent-child relationships defined by IDs. This tutorial shows how to transform such flat data into a hierarchical tree structure in JavaScript.
The Problem
Suppose we have an array of objects representing geographical regions from a database:
const arr = [
{"id":7,"name":"Kuwait","parentId":2},
{"id":4,"name":"Iraq","parentId":2},
{"id":10,"name":"Qatar","parentId":2},
{"id":2,"name":"Middle East","parentId":1},
{"id":3,"name":"Bahrain","parentId":2},
{"id":6,"name":"Jordan","parentId":2},
{"id":8,"name":"Lebanon","parentId":2},
{"id":1,"name":"Africa/Middle East","parentId":null},
{"id":5,"name":"Israel","parentId":2},
{"id":9,"name":"Oman","parentId":2}
];
console.log("Original flat structure:");
console.log(JSON.stringify(arr, null, 2));
Original flat structure:
[
{
"id": 7,
"name": "Kuwait",
"parentId": 2
},
{
"id": 4,
"name": "Iraq",
"parentId": 2
},
{
"id": 2,
"name": "Middle East",
"parentId": 1
},
{
"id": 1,
"name": "Africa/Middle East",
"parentId": null
}
]
Tree Transformation Function
We need to transform this flat structure into a hierarchical tree where each object contains a children array with its child nodes:
const transformTree = (data, root = null) => {
const res = [];
const map = {};
data.forEach((el) => {
// Initialize children array if it exists in map, or create empty array
el.children = map[el.id] && map[el.id].children || [];
map[el.id] = el;
if (el.parentId === root) {
// This is a root node
res.push(el);
} else {
// This is a child node
map[el.parentId] = map[el.parentId] || {};
map[el.parentId].children = map[el.parentId].children || [];
map[el.parentId].children.push(el);
}
});
return res;
};
// Transform the flat array into tree structure
const treeData = transformTree(arr);
console.log("Transformed tree structure:");
console.log(JSON.stringify(treeData, null, 2));
Transformed tree structure:
[
{
"id": 1,
"name": "Africa/Middle East",
"parentId": null,
"children": [
{
"id": 2,
"name": "Middle East",
"parentId": 1,
"children": [
{
"id": 7,
"name": "Kuwait",
"parentId": 2,
"children": []
},
{
"id": 4,
"name": "Iraq",
"parentId": 2,
"children": []
},
{
"id": 10,
"name": "Qatar",
"parentId": 2,
"children": []
},
{
"id": 3,
"name": "Bahrain",
"parentId": 2,
"children": []
},
{
"id": 6,
"name": "Jordan",
"parentId": 2,
"children": []
},
{
"id": 8,
"name": "Lebanon",
"parentId": 2,
"children": []
},
{
"id": 5,
"name": "Israel",
"parentId": 2,
"children": []
},
{
"id": 9,
"name": "Oman",
"parentId": 2,
"children": []
}
]
}
]
}
]
How the Algorithm Works
The transformation algorithm uses a map-based approach:
- Create a map: Store each node by its ID for quick lookup
- Process each node: Initialize children array and add to map
- Build relationships: If parentId is null, it's a root node. Otherwise, add to parent's children
- Handle order independence: The map allows children to be processed before their parents
Alternative Implementation
Here's a more explicit version that's easier to understand:
const buildTree = (flatArray) => {
const nodeMap = new Map();
const roots = [];
// First pass: create all nodes
flatArray.forEach(item => {
nodeMap.set(item.id, { ...item, children: [] });
});
// Second pass: build parent-child relationships
flatArray.forEach(item => {
const node = nodeMap.get(item.id);
if (item.parentId === null) {
roots.push(node);
} else {
const parent = nodeMap.get(item.parentId);
if (parent) {
parent.children.push(node);
}
}
});
return roots;
};
const alternativeTree = buildTree(arr);
console.log("Alternative implementation:");
console.log(JSON.stringify(alternativeTree, null, 2));
Alternative implementation:
[
{
"id": 1,
"name": "Africa/Middle East",
"parentId": null,
"children": [
{
"id": 2,
"name": "Middle East",
"parentId": 1,
"children": [
{
"id": 7,
"name": "Kuwait",
"parentId": 2,
"children": []
}
]
}
]
}
]
Conclusion
Converting flat database structures to hierarchical trees is essential for many applications. The map-based approach efficiently handles parent-child relationships regardless of data order, making it perfect for transforming database results into tree structures for UI components or data processing.
