如何过滤递归对象?

时间:2013-02-08 18:59:02

标签: c#

在我当前的项目中,我无法控制的方法向我发送了这种类型的对象:

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的{​​{1}}个对象结尾的路径,无论如何这片叶子的深度。

我完全不知道如何做到这一点,有人可以帮助我吗?

提前致谢!

修改

为了解释我遇到Shahrooz Jefri和dasblinkenlight提出的解决方案的问题,这是一张图片。左列是原始数据,没有过滤,右侧是过滤的数据。两种方法都提供相同的结果。 红色是问题。

enter image description here

3 个答案:

答案 0 :(得分: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);
        }
    }
}

答案 1 :(得分:1)

除了最初确定要显示哪些项目,如果数据量很大并且您希望用户经常折叠和展开部分,然后在每次点击后过滤我的结果都是缓慢的ui响应。

考虑Decorator模式或用相关信息标记每个节点的其他方式,以便每次点击后都不需要过滤。

答案 2 :(得分: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 s。