using System.Collections.Generic;
public string Group { get; set; }
public List<ValueAndUid> ValeursAndUids { get; set; } = new List<ValueAndUid>();
public string Item1 { get; set; }
public string Item2 { get; set; }
static void Main(string[] args)
List<Product> listProducts = new List<Product>
ValeursAndUids = new List<ValueAndUid>()
new() {Item1 = "Beige", Item2 = "QB32-20220325-486274"},
new() {Item1 = "Beige", Item2 = "QB32-20220325-106045"},
new() {Item1 = "Venezia", Item2 = "QB32-20220325-205994"},
new() {Item1 = "Venezia", Item2 = "QB32-20220325-270903"},
Group = "ref_commercial",
ValeursAndUids = new List<ValueAndUid>()
new() {Item1 = "29245", Item2 = "QB32-20220325-486274"},
new() {Item1 = "29245", Item2 = "QB32-20220325-106045"},
new() {Item1 = "29245", Item2 = "QB32-20220325-205994"},
new() {Item1 = "29245", Item2 = "QB32-20220325-270903"},
ValeursAndUids = new List<ValueAndUid>()
new() {Item1 = "172 B", Item2 = "QB32-20220325-486274"},
new() {Item1 = "172 B", Item2 = "QB32-20220325-106045"},
new() {Item1 = "1725 A", Item2 = "QB32-20220325-205994"},
new() {Item1 = "1725 A", Item2 = "QB32-20220325-270903"},
List<string> groups = listProducts.Select(p => p.Group).ToList();
IEnumerable<List<string>> products = listProducts
.SelectMany(product => product.ValeursAndUids, (product, valueAndUid) => new { product.Group, valueAndUid })
.GroupBy(item => item.valueAndUid.Item2)
List<string> path = g.Select(item => item.valueAndUid.Item1).ToList();
TreeNode root = new TreeNode("root", "");
foreach (List<string> path in products)
TreeNode current = parent;
for (int i = 0; i < path.Count; i++)
parent = parent.GetChild(groups[i], part);
root.Accept(new DepthTreeVisitor());
public void VisitTree(TreeNode tree);
public class DepthTreeVisitor : Visitor
public void VisitTree(TreeNode tree)
string indentString = new string(' ', 2 * level);
Console.WriteLine($"{indentString}{tree.GroupName} {tree.Value}");
foreach (TreeNode child in tree.Children)
public TreeNode(string groupName, string value)
Children = new HashSet<TreeNode>();
public string Value { get; }
public string GroupName { get; }
public ISet<TreeNode> Children { get; }
public void Accept(Visitor visitor)
public TreeNode GetChild(string group, string value)
foreach (TreeNode child in Children)
if (child.Value.Equals(value))
return GetChild(new TreeNode(group, value));
private TreeNode GetChild(TreeNode child)