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.

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);
}
}
}
}
view raw Program.cs hosted with โค by GitHub
And Output is:



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.

Comments

Post a Comment

Popular posts from this blog

Memoization: Speed up expensive functions in ASP .NET

LINQ :Querying in-memory collections/objects in ASP .NET