2013-02-08 44 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