Это более быстрый способ преобразовать иерархический список в список, основанный на том, сколько путей у него в облаке?
Я не мог знать, как правильно назвать этот вопрос.
Определение простое, это иерархический список (я также могу создать плоский список)
Simply show hierarchy view
hierarchy I able to get
1
-->2
-->3
-->4
-->5
-->6
flattened list I able to get
[1, 2, 3, 4, 5, 6]
результат, который я хотел, это
[
[1,2],
[1,3,4],
[1,3,5],
[1,6],
]
образец класса у меня есть
public class MemberNetworkViewModel
{
public int MemberGenerationNumber { get; set; }
public int MemberId { get; set; }
public int ParentId{ get; set; }
public List<MemberNetworkViewModel> children { get; set; }
}
Я мог бы сделать самый сложный путь, который состоит в том, чтобы попытаться выяснить, кто является последним узлом в этом списке иерархии, затем foeeach
их и получить их родителей по одному. Но я думаю, что будет лучший путь, есть идеи?
Текущее решение (обойти, я знаю, это грязно, возможно, ищет помощь для более коротких по linq?)
public List<List<MemberNetworkViewModel>> GetAllPossibleNetworkTreePath(
List<MemberNetworkViewModel> flatternMemberNetworkViewModel)
{
var possibleTreePaths = new List<List<MemberNetworkViewModel>>();
var lastNodes =
flatternMemberNetworkViewModel.Where(
x => flatternMemberNetworkViewModel.All(y => y.ParentId!= x.MemberId));
foreach (var lastNode in lastNodes)
{
var memberNetworkViewModels = new List<MemberNetworkViewModel>();
memberNetworkViewModels.Add(lastNode);
for (int index = 0; index < lastNode.MemberGenerationNumber; index++)
{
var parent =
flatternMemberNetworkViewModel.FirstOrDefault(
x => x.MemberId == memberNetworkViewModels.Last().ParentId);
memberNetworkViewModels.Add(parent);
}
memberNetworkViewModels = (from x in memberNetworkViewModels
orderby x.MemberGenerationNumber
select x).ToList();
possibleTreePaths.Add(memberNetworkViewModels);
}
return possibleTreePaths;
}
1 ответ
Если у вас есть исходные данные в дереве, это становится намного проще.
Похоже, у вас уже есть дерево, хранящееся в виде списка. Вам просто нужно знать элемент в списке, который представляет корень, и использовать его в качестве отправной точки для обхода дерева.
Вы можете написать метод общего назначения для обхода дерева и вывода маршрутов на все листья следующим образом:
public static void Flatten<T, U>(T root, Func<T, U> select, Func<T, IEnumerable<T>> children, Action<List<U>> output)
{
List<U> pathSoFar = new List<U>();
flatten(pathSoFar, root, select, children, output);
}
static void flatten<T, U>(List<U> pathSoFar, T root, Func<T, U> select, Func<T, IEnumerable<T>> children, Action<List<U>> output)
{
pathSoFar.Add(select(root));
bool any = false;
var offspring = children(root);
if (offspring != null)
{
foreach (var child in offspring)
{
any = true;
flatten(pathSoFar, child, select, children, output);
}
}
if (!any)
output(pathSoFar.ToList());
pathSoFar.RemoveAt(pathSoFar.Count-1);
}
Func, который вы передаете как output
Параметр будет вызываться один раз для каждого пути к листу.
Полное скомпилируемое консольное приложение, которое дублирует ваш ввод, выглядит следующим образом:
using System;
using System.Linq;
using System.Collections.Generic;
namespace ConsoleApp3
{
class Node
{
public int ID;
public List<Node> Children;
}
public class MemberNetworkViewModel
{
public int MemberGenerationNumber { get; set; }
public int MemberId { get; set; }
public int ParentId { get; set; }
public List<MemberNetworkViewModel> children { get; set; }
}
class Program
{
public static void Main(string[] args)
{
Node root =
new Node {ID = 1, Children = new List<Node>{
new Node {ID = 2 },
new Node {ID = 3, Children = new List<Node>{
new Node {ID = 4},
new Node {ID = 5}}},
new Node {ID = 6}
}};
Flatten(
root,
node => node.ID,
node => node.Children,
path => Console.WriteLine(string.Join(", ", path)));
}
public static void Flatten<T, U>(T root, Func<T, U> select, Func<T, IEnumerable<T>> children, Action<List<U>> output)
{
List<U> pathSoFar = new List<U>();
flatten(pathSoFar, root, select, children, output);
}
static void flatten<T, U>(List<U> pathSoFar, T root, Func<T, U> select, Func<T, IEnumerable<T>> children, Action<List<U>> output)
{
pathSoFar.Add(select(root));
bool any = false;
var offspring = children(root);
if (offspring != null)
{
foreach (var child in offspring)
{
any = true;
flatten(pathSoFar, child, select, children, output);
}
}
if (!any)
output(pathSoFar.ToList());
pathSoFar.RemoveAt(pathSoFar.Count-1);
}
}
}
Для тебя MemberNetworkViewModel
класс вы бы назвали это так:
MemberNetworkViewModel root = whatever;
Flatten(
root,
node => node.MemberId,
node => node.children,
path => Console.WriteLine(string.Join(", ", path)));