using System.Collections.Generic;
public static void Main()
Console.WriteLine("Hello World");
var a = new Category(){ Name = "A", Path = "A" };
var b = new Category(){ Name = "B", Path = "A/B" };
var c = new Category(){ Name = "C", Path = "A/B/C" };
var vms = Map(new[]{a,b,c});
public class CategoryViewModel
public Guid Id { get; set; }
public Guid DomainId { get; set; }
public string Name { get; set; } = default!;
public string Path { get; set; } = default!;
public CategoryViewModel? Parent { get; set; }
public List<CategoryViewModel> Children { get; set; } = new List<CategoryViewModel>();
public void Print(string root)
foreach(var children in this.Children)
public Guid Id { get; set; }
public Guid DomainId { get; set; }
public string Name { get; set; } = default!;
public string Path { get; set; } = default!;
public static List<CategoryViewModel> Map(IEnumerable<Category> input)
.GroupBy(p => p.Path, StringComparer.OrdinalIgnoreCase)
.ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase);
var destination = new Dictionary<string, CategoryViewModel>();
CategoryViewModel RecursiveBuild(
CategoryViewModel parent)
var path = string.Join("/", parts.Take(index + 1));
if (destination.ContainsKey(path) == false)
CategoryViewModel category = null;
if (source.ContainsKey(path))
category = Map(source[path]);
category = new CategoryViewModel
destination[path] = category;
category.Parent = parent;
parent.Children.Add(category);
return index < parts.Length - 1 ? RecursiveBuild(parts, index + 1, destination[path]) : destination[path];
foreach (var item in input)
var parts = path.Split('/');
RecursiveBuild(parts, 0, null);
var roots = destination.Values.Where(c => c.Parent == null).ToList();
return new List<CategoryViewModel>(roots);
public static CategoryViewModel Map(Category source)
DomainId = source.DomainId,