2016-11-17 231 views
1

我有一个小程序,它应该创建一个简单的菜单。 我目前的问题是,我有一个对象应该填充主菜单点,然后所有菜单点下。 我的问题是,一个IList中可以有第二或第三的IList和我真的不知道如何interate在n ILists通过对象迭代对象列表

例子:

MainNodeObj: 
NodeDtoId = 1, 
ItemCode = 'A' 
IList<NodeDTO> ChildMenuNodes 
{ 
    MainNodeObj: 
    NodeDtoId = 2, 
    ItemCode = '2', 
    IList<NodeDTO> ChildMenuNodes 
    { 
    MainNodeObj: 
    NodeDtoId = 3, 
    ItemCode = '3', 
    } 

我的问题是,每个ChildNode可以有一个新的childnode并为每个子节点,我将创建新的对象......听起来很容易,但我不知道如何来遍历n个新的childNodes

方法:

private IEnumerable<NodeDTO> SortedNodes(int id) 
     { 
      var nodes = LoadMenuNodes(id); 
      foreach (MenuNode menuNode in nodes 
       .Where(s => s.MenuItemId == null && s.ParentNodeId == null) 
       .OrderBy(x => x?.Sequence)) 
      { 
       NodeDTO tmpMenuNode = new NodeDTO(); 
       tmpMenuNode.MenuNodeDtoId = menuNode.Id; 
       tmpMenuNode.MenuItemCode = menuNode.MenuItem?.Code; 
       tmpMenuNode.ChildMenuNodes = LoadChildNodes(menuNode.ChildMenuNodes).ToList(); 
       yield return tmpMenuNode; 
      } 
     } 
    private IEnumerable<NodeDTO> LoadChildNodes(MenuNodeList menuNode) 
     { 
      foreach (MenuNode childNode in menuNode) 
      { 
       NodeDTO tmChildNode = new NodeDTO(); 
       tmChildNode.MenuNodeDtoId = childNode.Id; 
       tmChildNode.MenuItemCode = childNode?.MenuItem?.Code; 
       tmChildNode.ChildMenuNodes = null; 
       yield return tmChildNode; 
      } 
     } 



     public class NodeDTO 
    { 
     public int NodeDtoId { get; set; } 
     public string ItemCode { get; set; } 
     public IList<NodeDTO> ChildMenuNodes { get; set; } 
    } 
+0

我的问题是,每个childnode可以有一个新的子节点 –

+0

是否DTO需要有所有孩子们在一个单子里?还是需要保持分层布局? – ErazerBrecht

+0

它看起来像'LoadChildNodes'作为递归函数可以帮助你。 –

回答

1

难道你不能只使用resursive功能

通过将此放置在LoadChildNodes函数中。

tmpChildNode.ChildMenuNodes = LoadChildNodes(childNode.ChildMenuNodes).ToList();

+0

这样LoadChildNodes函数再次调用自己?在foreach之后? –

+0

每次迭代(在foreach中)它都会自动载入当前孩子的孩子。我不得不承认我对“收益”的了解有限。 – ErazerBrecht

+1

它的工作原理,谢谢! –

2

我喜欢的通用扩展扁平化树样式对象

public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source, Func<T,IEnumerable<T>> selector) 
{ 
    return source.SelectMany(o => selector(o).Flatten(selector)).Concat(source); 
} 

如何调用:

// create a new list for the node 
var nodes = new IEnumerable<NodeDTO>(); 

// add the root node 
nodes.Add(rootNode); // add the root node 

// flatten the list 
var flatList = = rootNode.Flatten(o=> o.ChildMenuNodes); 
+0

不相关,但它应该是选择器而不是谓词 – MistyK

+0

对此有什么好处?速度更快吗? –

+1

对任何具有其自己类型集合的对象的可重用性。 – Franck