2016-11-17 235 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