2017-03-21 16 views
2

私は単一のリストまたは要素を作成する関数を作成しようとしています。LINQ複数のリストを一覧表示します。単一のリストを返す

この要素のリストは、リストの動的リストに含まれる値に基づいてソロを決定します。 リストAたとえば

は保持一覧B.及びリストBを保持しているオブジェクトは、彼らが特別な値を保持している可能性があるリストA、B又はC内のリストC

を保持しているオブジェクトを保持しています。

すべてのリストを検索し、特別な値を保持する値だけを返す関数を作成する必要があります。

私は再帰関数を調べてみましたが、私は近いと思います。

public ObservableCollection<ListViewItem> RecursiveActionBuilder(List<IMetaData> pList) 
    { 
     if (pList == null) 
      return null; 

     List<ActionObject> actions = new List<ActionObject>(); 

     for (int x = 0; x < pList.Count; x++) 
     { 
      ActionObject child = RecursiveActionBuilder(pList[x]); 
      if (child == null) 
       continue; 
      else 
       actions.Add(child); 
     } 

     ObservableCollection<ListViewItem> items = new ObservableCollection<Models.Items.ListViewItem>(); 

     for (int x = 0; x < actions.Count; x++) 
      items.Add(new ListViewItem() 
      { 
       Values = new ListViewValue[] 
       { 
        new ListViewValue() { Value = actions[x].Command }, 
        new ListViewValue() { Value = actions[x].Target }, 
        new ListViewValue() { Value = actions[x].Value }, 
        new ListViewValue() { Value = actions[x].Comment } 
       } 
      }); 

     return items; 
    } 

    public ActionObject RecursiveActionBuilder(IMetaData pObj) 
    { 
     if (pObj == null) 
      return null; 

     if (pObj.Children == null) 
     { 
      if (pObj.Tag == Enums.TestType.Action) 
       return pObj as ActionObject; 
      else 
       return null; 
     } 


     ActionObject action = new ActionObject(); 

     for (int x = 0; x < pObj.Children.Count; x++) 
     { 
      ActionObject child = RecursiveActionBuilder(pObj.Children[x]); 
      if (child == null) 
       continue; 
      else return child; 
     } 
     return null; 
    } 

しかし、すべての 'アクション'を取得しているわけではありません。

思考?質問が暗示するように、この方法

public ActionObject RecursiveActionBuilder(IMetaData pObj) 

ではなく、複数のオブジェクトで、単一のオブジェクトを返すので

答えて

2

問題が明らかです。

これは修正することができますが、少し異なるアプローチを提案します。 DRY原則に従い

、あなたは本当にこのようなシナリオに必要なもののようなツリー構造を平坦化する方法などのLINQは、あなたのIMetaData(あなたのコードに応じてList<IMetaData> Childrenプロパティ/フィールドが含まれています)。たとえば、あなたがHow to flatten tree via LINQ?に私の答えからカスタム拡張メソッドを使用することができます。

public static class TreeHelpers 
{ 
    public static IEnumerable<T> Expand<T>(
     this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector) 
    { 
     var stack = new Stack<IEnumerator<T>>(); 
     var e = source.GetEnumerator(); 
     try 
     { 
      while (true) 
      { 
       while (e.MoveNext()) 
       { 
        var item = e.Current; 
        yield return item; 
        var elements = elementSelector(item); 
        if (elements == null) continue; 
        stack.Push(e); 
        e = elements.GetEnumerator(); 
       } 
       if (stack.Count == 0) break; 
       e.Dispose(); 
       e = stack.Pop(); 
      } 
     } 
     finally 
     { 
      e.Dispose(); 
      while (stack.Count != 0) stack.Pop().Dispose(); 
     } 
    } 
} 

今、あなたはあなたの具体的な課題を解決するためのLINQのフルパワーを利用することができます:私は

public ObservableCollection<ListViewItem> RecursiveActionBuilder(List<IMetaData> pList) 
{ 
    if (pList == null) 
     return null; 

    var items = pList 
     .Expand(e => e.Children) 
     .Select(e => e.Children == null && e.Tag == Enums.TestType.Action ? e as ActionObject : null) 
     .Where(e => e != null) 
     .Select(e => new ListViewItem() 
     { 
      Values = new ListViewValue[] 
      { 
       new ListViewValue() { Value = e.Command }, 
       new ListViewValue() { Value = e.Target }, 
       new ListViewValue() { Value = e.Value }, 
       new ListViewValue() { Value = e.Comment } 
      } 
     }); 

    return new ObservableCollection<ListViewItem>(items); 
}   
+0

おかげでイワン、申し訳ありませんただあなたに戻ってきます。私は数時間を与えて、私はあなたの答えをできるだけ早く確認することができます! –

+0

問題ない仲間、私は急いでいません:) –

+0

これは素晴らしいです!アイワンありがとう! –

関連する問題