Creating Hierarchical Structure in C#
There are many instances encountered by developer to create hierarchical data structure.
For example, Category Hierarchy in E-Commerce.
- Electronics
- Mobiles
- Android Mobiles
- Samsung
- Motorola
- One Plus
- Windows Mobiles
- Lumia
- Laptops
- Gaming Laptops
- Dell
- 4GB RAM
- 6GB RAM
- 8GB RAM
- HP
- 4GB RAM
- 6GB RAM
- 8GB RAM
- Appliances
- AC
- Inverter AC
- Window AC
Almost in all instances this data will come from single table (Assuming data is stored in database).
Table structure would be.
Category
|
||
Column Name
|
DataType
|
Description
|
CategoryId
|
bigint
|
PK
|
Name
|
nvarchar(100)
|
Not Null
|
ParentCategoryId
|
bigint
|
default(0)
|
All Category have ParentCategoryId value, which refers to CategoryId of column allowing us to perform self join.
ParentCategoryId=0 informs that the category don't have any parent.i.e topmost category.
Now above hierarchy will be stored as follows:
CategoryId
|
Name
|
ParentCategoryId
|
1
|
Electronics
|
0
|
2
|
Appliances
|
0
|
3
|
Mobiles
|
1
|
4
|
Laptops
|
1
|
5
|
AC
|
2
|
6
|
Android Mobiles
|
3
|
7
|
Windows Mobiles
|
3
|
8
|
Samsung
|
6
|
9
|
Motorola
|
6
|
10
|
One Plus
|
6
|
11
|
Lumia
|
7
|
12
|
Gaming Laptops
|
4
|
13
|
Dell
|
4
|
14
|
HP
|
4
|
15
|
4GB RAM
|
13
|
16
|
6GB RAM
|
13
|
17
|
8GB RAM
|
13
|
18
|
4GB RAM
|
14
|
19
|
6GB RAM
|
14
|
20
|
8GB RAM
|
14
|
21
|
Inverter AC
|
5
|
22
|
Window AC
|
5
|
To Create Hierarchical structure of above data like parent-child list,we will use self-calling function. (This will work for all programming language)
Here is Console program for this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
namespace HierarchyStructure | |
{ | |
public class Category | |
{ | |
public long CategoryId { get; set; } | |
public string Name { get; set; } | |
public long ParentCategoryId { get; set; } | |
} | |
public class CategoryHierarchy | |
{ | |
public Category Category { get; set; } | |
public List<CategoryHierarchy> Children { get; set; } | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
//Get Category List | |
var categoryList = GetCategoriesFromJsonFile(); | |
var hierarchy = GenerateHierarchy(categoryList); | |
Console.ReadLine(); | |
} | |
/// <summary> | |
/// Generates Parent-Child Hierarchy and prints on console before returning | |
/// </summary> | |
/// <param name="categoryList">List of Category Objects</param> | |
/// <param name="parentId">Parent Category Id default(0) for Main Categories</param> | |
/// <param name="indent">string to represent separation between different level</param> | |
/// <returns>Category Hierarchy List</returns> | |
public static List<CategoryHierarchy> GenerateHierarchy(List<Category> categoryList, long parentId = 0, string indent = "") | |
{ | |
//use to store current level categories | |
var catHierarchy = new List<CategoryHierarchy>(); | |
//Get current Level categories | |
var currentLevelCategories = categoryList.Where(c => c.ParentCategoryId == parentId).ToList(); | |
//Loop through current level categories | |
foreach (var cat in currentLevelCategories) | |
{ | |
Console.WriteLine($"{indent}{cat.Name}"); | |
catHierarchy.Add(new CategoryHierarchy() | |
{ | |
Category = cat, | |
//Get Child hierarchy for current category i.e cat | |
Children = GenerateHierarchy(categoryList, cat.CategoryId, string.Concat(indent, "--")) // Calling self function | |
}); | |
} | |
return catHierarchy; | |
} | |
/// <summary> | |
/// Create List of Category from JSON file | |
/// </summary> | |
/// <returns></returns> | |
public static List<Category> GetCategoriesFromJsonFile() | |
{ | |
using (var reader = new StreamReader("E:/Projects/DemoConsole/HierarchyStructure/category.json")) | |
{ | |
var categoryData = reader.ReadToEnd(); | |
return JsonConvert.DeserializeObject<List<Category>>(categoryData); | |
} | |
} | |
} | |
} |
And Output is:
The JSON data used in above program is:
For any query comment below.
The JSON data used in above program is:
[
{
"CategoryId": 1,
"Name": "Electronics",
"ParentCategoryId": 0
},
{
"CategoryId": 2,
"Name": "Appliances",
"ParentCategoryId": 0
},
{
"CategoryId": 3,
"Name": "Mobiles",
"ParentCategoryId": 1
},
{
"CategoryId": 4,
"Name": "Laptops",
"ParentCategoryId": 1
},
{
"CategoryId": 5,
"Name": "AC",
"ParentCategoryId": 2
},
{
"CategoryId": 6,
"Name": "Android Mobiles",
"ParentCategoryId": 3
},
{
"CategoryId": 7,
"Name": "Windows Mobiles",
"ParentCategoryId": 3
},
{
"CategoryId": 8,
"Name": "Samsung",
"ParentCategoryId": 6
},
{
"CategoryId": 9,
"Name": "Motorola",
"ParentCategoryId": 6
},
{
"CategoryId": 10,
"Name": "One Plus",
"ParentCategoryId": 6
},
{
"CategoryId": 11,
"Name": "Lumia",
"ParentCategoryId": 7
},
{
"CategoryId": 12,
"Name": "Gaming Laptops",
"ParentCategoryId": 4
},
{
"CategoryId": 13,
"Name": "Dell",
"ParentCategoryId": 4
},
{
"CategoryId": 14,
"Name": "HP",
"ParentCategoryId": 4
},
{
"CategoryId": 15,
"Name": "4GB RAM",
"ParentCategoryId": 13
},
{
"CategoryId": 16,
"Name": "6GB RAM",
"ParentCategoryId": 13
},
{
"CategoryId": 17,
"Name": "8GB RAM",
"ParentCategoryId": 13
},
{
"CategoryId": 18,
"Name": "4GB RAM",
"ParentCategoryId": 14
},
{
"CategoryId": 19,
"Name": "6GB RAM",
"ParentCategoryId": 14
},
{
"CategoryId": 20,
"Name": "8GB RAM",
"ParentCategoryId": 14
},
{
"CategoryId": 21,
"Name": "Inverter AC",
"ParentCategoryId": 5
},
{
"CategoryId": 22,
"Name": "Window AC",
"ParentCategoryId": 5
}
]
For any query comment below.
Awesome ๐๐๐๐๐
ReplyDelete