2013-02-08 86 views
6

在我當前的項目,我不控制的方法把我這種類型的對象:如何篩選遞歸對象?

public class SampleClass 
{ 
    public SampleClass(); 

    public int ID { get; set; } 
    public List<SampleClass> Items { get; set; } 
    public string Name { get; set; } 
    public SampleType Type { get; set; } 
} 

public enum SampleType 
{ 
    type1, 
    type2, 
    type3 
} 

我在TreeView顯示這些數據,但我想,只顯示SampleClass對象結束路徑他們的Type屬性設置爲type3,無論這個葉子的深度如何。

我完全不知道如何做到這一點,有人可以幫助我嗎?

在此先感謝!

編輯

爲了解釋我與Shahrooz Jefri和dasblinkenlight提出的解決方案滿足了問題,這裏是一個圖片。左欄是原始數據,沒有過濾,右欄是過濾的數據。兩種方法都提供相同的結果。 紅色是問題所在。

enter image description here

+1

如果路徑到TYPE3 LIEF在2型節點應該發生什麼? – dasblinkenlight 2013-02-08 19:05:26

+0

我必須有完整的路徑,所以它會給類似'type1> type2> ...> type3' – Shimrod 2013-02-08 19:12:19

回答

0

試試這個辦法:

static bool ShouldKeep(SampleClass item) { 
    return (item.Type == SampleType.type3 && item.Items.Count == 0) 
     || item.Items.Any(ShouldKeep); 
} 

static SampleClass Filter(SampleClass item) { 
    if (!ShouldKeep(item)) return null; 
    return new SampleClass { 
     Id = item.Id 
    , Name = item.Name 
    , Type = item.Type 
    , Items = item.Items.Where(ShouldKeep).Select(x=>Filter(x)).ToList() 
    }; 
} 

上面的代碼假定葉Items是空列表,而不是null秒。

+0

我得到了同樣的問題,上面的答案,http://stackoverflow.com/questions/14779487/how- to-filter-a-recursive-object#comment20692674_14779539 – Shimrod 2013-02-08 19:19:09

+0

@Shimrod我沒有意識到,通過「路徑結尾」你的意思是'type3'必須在鏈的末尾。看看編輯。 – dasblinkenlight 2013-02-08 19:22:38

+0

問題仍然存在,我想它來自Items集合重建的方式。我編輯了我的問題來解釋它 – Shimrod 2013-02-08 19:32:07

1

除了最初確定顯示哪些項目,如果數據大小很大,並且您希望用戶經常摺疊和展開節,然後在每次點擊後過濾,我的結果是響應速度慢。

考慮裝飾模式或其他方式標記每個節點與相關的信息,以便每次點擊後不需要過濾。

+0

這不會是問題,這個想法是隻過濾一次,數據在樹顯示後不會改變。也不會有那麼多的數據,它只是需要分層顯示,我沒有權力。 – Shimrod 2013-02-08 19:42:15

+0

數據不會改變,但每次用戶擴展節點時,都必須遍歷它以進行過濾。如果數據大小不像你說的那麼大,那麼它可能不是問題 – 2013-02-08 19:47:19

2

使用此篩選方法:

public void Filter(List<SampleClass> items) 
{ 
    if (items != null) 
    { 
     List<SampleClass> itemsToRemove = new List<SampleClass>(); 

     foreach (SampleClass item in items) 
     { 
      Filter(item.Items); 
      if (item.Items == null || item.Items.Count == 0) 
       if (item.Type != SampleType.type3) 
        itemsToRemove.Add(item); 
     } 

     foreach (SampleClass item in itemsToRemove) 
     { 
      items.Remove(item); 
     } 
    } 
} 
+0

我試過你的方法了,我也遇到了與其他問題相同的問題。 – Shimrod 2013-02-08 20:03:58

+0

@Shimrod會有什麼問題?我已經測試了多個孩子,並且它只返回以'type3'結尾的路徑,完全按照您的需要。你可以在我的代碼不起作用的地方發佈樣本嗎? – 2013-02-08 20:12:59

+0

嗨大衛。問題是我在我的問題的編輯中描述的問題。不僅返回類型3的葉子,還返回它的父級的兄弟姐妹。 – Shimrod 2013-02-08 20:28:07