这是根据云有多少路径将层次结构列表转换为列表的更快方法吗?
Is that a faster way to convert hierarchy list to a list based on how many path it cloud have?
我不知道这个问题的正确命名是什么。
定义很简单,就是层级列表(我也可以生成扁平化列表)
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],
]
样本class我有
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;
}
如果您将源数据放在树中,事情就容易多了。
看起来您已经有了一个列表形式的树。你只需要知道列表中代表根的元素,并以此为起点遍历树。
你可以写一个general-purpose方法来遍历树并输出到所有叶子的路径,像这样:
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);
}
您作为 output
参数传递的 Func 将针对每个叶子路径调用一次。
复制您的输入的完整可编译控制台应用程序如下:
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
class 你可以这样称呼它:
MemberNetworkViewModel root = whatever;
Flatten(
root,
node => node.MemberId,
node => node.children,
path => Console.WriteLine(string.Join(", ", path)));
我不知道这个问题的正确命名是什么。
定义很简单,就是层级列表(我也可以生成扁平化列表)
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],
]
样本class我有
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;
}
如果您将源数据放在树中,事情就容易多了。
看起来您已经有了一个列表形式的树。你只需要知道列表中代表根的元素,并以此为起点遍历树。
你可以写一个general-purpose方法来遍历树并输出到所有叶子的路径,像这样:
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);
}
您作为 output
参数传递的 Func 将针对每个叶子路径调用一次。
复制您的输入的完整可编译控制台应用程序如下:
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
class 你可以这样称呼它:
MemberNetworkViewModel root = whatever;
Flatten(
root,
node => node.MemberId,
node => node.children,
path => Console.WriteLine(string.Join(", ", path)));