LINQ:选择没有父节点的节点

时间:2011-06-15 10:25:20

标签: linq

我有一个简单的树结构,如下所示:

Node
{
   int Id;
   int ParentId;
   int Name;
}

将LINQ与List< Node>一起使用,如何选择同一列表中没有父节点的所有节点?

示例:

Id  ParentId
1   0
2   1
3   1
4   2
5   4
8   6

在上表中,Id 1和8的节点在集合中没有父节点。

4 个答案:

答案 0 :(得分:1)

我会用:

var parents = new HashSet<int>(nodes.Select(node => node.ParentId));
var orphans = nodes.Where(node => !parents.Contains(node.Id));

可以使用:

var orphans = nodes.Where(node => !nodes.Select(x => x.ParentId)
                                        .Contains(node.Id));

但这将是O(n 2 )操作,而第一个版本是O(n),假设正常的散列效率。显然,如果n很小,那就无关紧要了......

答案 1 :(得分:1)

var res = nodes.Except(from node in nodes
                       join pnode in nodes
                         on node.ParentId equals pnode.Id
                     select node);

或:

var res = from node in nodes
          join pnode in nodes
          on node.ParentId equals pnode.Id into jnodes
          from jnode in jnodes.DefaultIfEmpty()
          where jnode == null
          select node;

或:

var res = nodes.Where(np => !nodes.Any(n => np.ParentId == n.Id));

答案 2 :(得分:1)

var items = from n in list
            where list.Count(p => n.ParentId == p.Id) == 0
            select n;

答案 3 :(得分:0)

var ids = list.Select(i => i.Id).ToList();
var result = list.Where(i => !ids.Contains(i.ParentId)).Select(i => i);

编辑:添加.ToList()以确保包含工作 EDIT2:改变了操作以回答正确的问题。