最简单的Recurse Over Object Tree方法

时间:2016-03-25 20:42:24

标签: c# algorithm recursion tree treeview

我有一个基类:

public abstract class BaseClass{ 
    public bool IsSelected {get; set;}   
}

具有表示层次结构的集合的派生类:

public class DerivedOne : BaseClass{
    public ObservableCollection<BaseClass> Children {get; set;}
}

另一个派生类:

public class DerivedTwo : BaseClass{

}

查找DerivedOne根下IsSelected设置为true的所有元素的最简单方法是什么?

3 个答案:

答案 0 :(得分:1)

你省略了一些要求细节,但我认为这样的事情应该有效:

public IEnumerable<BaseClass> AllIsSelected(BaseClass root)
{
    if (root.IsSelected)
    {
        yield return root;
    }
    var composite = root as DerivedOne;
    if (composite != null)
    {
        foreach (var v in composite.Children)
        {
            foreach (var x in AllIsSelected(v))
            {
                yield return x;
            }
        }
    }
}

当然,如果您想要一次完整列表,则可以构建列表而不是使用&#39; yield&#39;。

这与此处讨论的设计相同:IEnumerable and Recursion using yield return

正如另一个答案所说,你可以使用LINQ来缩短它。此版本避免制作临时列表。

public IEnumerable<BaseClass> AllIsSelected(BaseClass root)
    {
        if (root.IsSelected)
        {
            yield return root;
        }
        var composite = root as DerivedOne;
        if (composite != null)
        {
            foreach (var x in composite.Children.SelectMany(v => AllIsSelected(v)))
            {
                yield return x;
            }
        }
    }

答案 1 :(得分:0)

最简单的方法是使用带递归的LINQ

public IEnumerable<BaseClass> GetAllSelectedChildren(DerivedOne derivedOne)
{
    return derivedOne.Children.SelectMany(GetAllSelected);
}

public IEnumerable<BaseClass> GetAllSelected(BaseClass baseClass)
{
    var selected = new List<BaseClass>();

    if(baseClass.IsSelected)
    {
        selected.Add(baseClass);
    }

    var derivedOne = baseClass as DerivedOne;
    if(derivedOne != null)
    {
        selected.AddRange(GetAllSelectedChildren(derivedOne));
    }

    return selected;
}

答案 2 :(得分:0)

使用简单的Linq

  return root.Children
             .SelectMany(c => new[]{ c }.Concat(c.Children)) // flatten the structure including self node.
             .Where(e => e.IsSelected) // filter selected items
             .ToList();
相关问题