Постройте иерархию в составном шаблоне из случайного положения эффективным способом

#c# #performance #.net-core

Вопрос:

У меня есть функция, которая строит список деревьев (в списке находятся корневые элементы с измененными дочерними коллекциями) из случайных точек в их иерархии. С небольшими списками это работает нормально, но с большими списками у меня возникают серьезные проблемы с производительностью. Большая проблема, с которой я сталкиваюсь, заключается в том, что мне нужны только соответствующие ветви в конечном дереве, но функция может получать несколько элементов из одной и той же ветви, но на разных уровнях или на одном уровне.

Допустим, мой список выглядит так:

 Element /1/ 
 |_Sub Element /1/1/
 |_Sub Element /1/2/
   |_Sub Element /1/2/1/
     |_Sub Element /1/2/1/1/
     |_Sub Element /1/2/1/2/
 |_Sub Element /1/3/
   |_Sub Element /1/3/1/
Element /2/
 |_Sub Element /2/1/
   |_Sub Element /2/1/1/
 |_Sub Element /2/2/
   |_Sub Element /2/2/1
     |_Sub Element /2/2/1/1
 

Функция поиска дает мне эти элементы из деревьев:

 Sub Element /1/2/1/2/
Sub Element /1/3/1/
Sub Element /2/2/1/
Sub Element /2/2/1/1
 

Мой ожидаемый результат будет:

 Element /1/ 
 |_Sub Element /1/2/
   |_Sub Element /1/2/1
     |_Sub Element /1/2/1/2/ * Element from input
 |_Sub Element /1/3/
   |_Sub Element /1/3/1/ * Element from input
Element /2/
 |_Sub Element /2/2/
   |_Sub Element /2/2/1 * Element from input
     |_Sub Element /2/2/1/1 * Element from input

 

Вот моя структура элементов и функция, которая генерирует желаемый результат:

 public class Element
{
   //the parent and children property is populated with entity framework
   public int Id {get;set;}
   public string Name {get;set;}
   public int? ParentId {get;set} //a root element has ParentId = null and Parent = null
   public Element Parent {get;set;}
   public ICollection<Element> Children {get;set;}
}

private List<Element> MakeTreeFromMatches(List<Element> flatMatches, List<Element> returnList)
{
    List<Element> tempList = new();
    foreach (var item in flatMatches)
    {
        if (item != null)
        {
            if (item.Parent != null)
            {
                var newChildren = flatMatches.Where(x => x.ParentId == item.Parent.Id).ToList();
                newChildren = newChildren.Distinct().ToList();
                item.Parent.Children = newChildren; 
                tempList.Add(item.Parent);
            }
            else
            {
                returnList.Add(item);
                returnList = returnList.Distinct().ToList();
            }
            returnList.AddRange(MakeTreeFromMatches(tempList, new List<Element>()));
        }
    }
    returnList = returnList.Distinct().ToList();
    return returnList;
}
 

How can I make this more efficient ?