首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >遍历树并在C#中获取特定的子级

遍历树并在C#中获取特定的子级
EN

Stack Overflow用户
提问于 2017-10-22 09:27:46
回答 2查看 522关注 0票数 0

我目前正在使用这样定义的树结构

代码语言:javascript
复制
public class TreeNode
{
   private ObservableCollection<TreeItem> nodeItems;
   private ObservableCollection<TreeNode> nodeChildren;
   //public "NodeItems" and "NodeChildren" getters and setters
}

public class TreeItem
{
   private bool isSelected;
   private string Name;
   //public "IsSelected" and "Name" getters and setters
}

public class Tree
{
   private TreeNode rootNode;
   //public getters and setters properties
}

我正在尝试编写一个函数或一个public属性,它递归地获取具有isSelected == trueTree中的所有isSelected == true,并使其成为一个平面集合。

因此,我在TreeNode类中编写了这个函数,它递归地在子类中导航:

代码语言:javascript
复制
public ObservableCollection<TreeItem> SelectedItems()
    {
        ObservableCollection<TreeItem> tempCollection = new ObservableCollection<TreeItem>();
        if (nodeItems != null)
        {
            foreach (TreeItem item in nodeItems)
            {
                if (item.IsSelected == true)
                {
                    tempCollection.Add(item);
                }
            }
        }
        if (nodeChildren != null)
        {
            foreach (TreeNode node in nodeChildren)
            {
                tempCollection.Concat(node.SelectedItem()); 
            }
        }
        return tempCollection;
    }

但是总是在末尾返回一个空集合。

我如何纠正它,并可能改进它(通过使用Lambda表达式或属性)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-22 09:40:35

Concat函数在ObservableCollection上不修改任何参数。您必须将结果对象分配给您的tempCollection

代码语言:javascript
复制
    if (nodeChildren != null)
    {
        foreach (TreeNode node in nodeChildren)
        {
            tempCollection = new ObservableCollection<TreeNode>(tempCollection.Concat(node.SelectedItem())); 
        }
    }

编辑:或者,您可以使用重载的私有方法来避免使用如此多的临时集合:

代码语言:javascript
复制
public ObservableCollection<TreeItem> SelectedItems()
{
    ObservableCollection<TreeItem> toReturn = new ObservableCollection<TreeItem>();
    SelectedItems(toReturn);
    return toReturn;
}

private void SelectedItems(ObservableCollection<TreeItem> tempCollection)
{
    if (nodeItems != null)
    {
        foreach (TreeItem item in nodeItems)
        {
            if (item.IsSelected == true)
            {
                tempCollection.Add(item);
            }
        }
    }
    if (nodeChildren != null)
    {
        foreach (TreeNode node in nodeChildren)
        {
            node.SelectedItems(tempCollection);
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2017-10-22 11:22:50

您可以将树的定义简化为以下内容:

代码语言:javascript
复制
public class Tree : ObservableCollection<Tree>
{
    public ObservableCollection<TreeItem> nodeItems;
}

现在你可以这样做了:

代码语言:javascript
复制
public IEnumerable<TreeItem> FlattenIsSelected(Tree tree)
{
    return tree.nodeItems.Where(x => x.isSelected)
        .Concat(tree.SelectMany(t => FlattenIsSelected(t)));
}

如果您保留当前的定义,就不会更困难了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46872498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档