我有一个定期班-我在下面简化了它。
public class SiloNode
{
public string Key { get; private set; }
public string Url { get; private set; }
public List<SiloNode> Children { get; private set; }
}
尽管从理论上讲,它可以永远嵌套,但是节点将永远只下降两个级别。因此,顶级节点可以有一个孩子,但是一个孩子不能有孩子。
我有一个主列表,其中包含所有顶级节点及其嵌套的子节点。
但是,我需要将所有节点放入一个平面列表中-节点1,其子节点,然后是节点2,等等。
我在这方面的知识有限,但是我可以在主列表上执行诸如foreach
之类的操作,并创建一个新列表,如下所示:
public IEnumerable<SiloNode> GetLinks(IEnumerable<SiloNode> masterList)
{
var newList = new List<SiloNode>();
foreach (var node in masterList)
{
newList.Add(node);
newList.AddRange(node.Children);
}
return newList;
}
但是,我知道可能有更好的方法可用,但是我无法弄清楚如何将foreach
转换为Linq
语句来执行相同的操作。换句话说,一起选择父级及其子级。
任何帮助表示赞赏。
答案 0 :(得分:2)
您可以使用SelectMany
,只需将单亲父母及其子女联系在一起:
List<SiloNode> newList = masterList.SelectMany(n => new[]{ n }.Concat(n.Children)).ToList();
答案 1 :(得分:2)
masterList
已包含父节点,并连接子节点
var nodes = masterList.Concat(masterList.SelectMany(x=> x.Children));
答案 2 :(得分:2)
如果只有两个级别,则应该执行以下操作:
public IEnumerable<SiloNode> GetLinks(IEnumerable<SiloNode> masterList)
{
return masterList.SelectMany(m => new SiloNode[] { m }.Concat(m.Children));
}
答案 3 :(得分:2)
如果您想保留订单并压平一个以上的孩子水平,我认为类似的事情就可以了。 CheckBox
或在循环ToggleButton
var nodes = GetLinks(masterList);
答案 4 :(得分:0)
我以前看过这个答案,但是找不到问题。这可以满足您的需要,而无需深入节点结构:
public IEnumerable<SiloNode> Flatten(IEnumerable<SiloNode> nodes)
{
var queue = new Queue<SiloNode>();
foreach (var node in nodes)
{
queue.Enqueue(node);
}
while (queue.Count > 0)
{
var node = queue.Dequeue();
foreach (var child in node.Children)
{
queue.Enqueue(child);
}
yield return node;
}
}
编辑:这不会保留您想要的顺序,但是您可以使用堆栈而不是队列。