2

我在 C# 中有一个对象,它有一些属性:

// Pseudo class
public class
{
    Id;
    To;
    From;
}

我有很多该类的实例Collection。这可能看起来像这样:

object 1:
  Id: 1
  To: "PathA"
  From: "PathB"

object 2:
  Id: 2
  To: "PathB"
  From: "PathC"

object 3:
  Id: 3
  To: "PathC"
  From: "PathA"

现在我想要做的是从该集合中获取所有项目,其中的值To没有出现在From任何对象中。这将导致以下结果:

object 1:
  Id: 1
  To: "PathA"
  From: "PathB"

object 2:
  Id: 2
  To: "PathB"
  From: "PathC"

因为最后一个对象Id: 3hasPathAFrom属性中,它已经存在于To属性中的某个位置。

如何使用 Linq 查询来做到这一点?

4

5 回答 5

2

那么,如何解决这个问题呢?首先,您可以创建 的所有值的索引To。然后,根据From属性过滤您的序列...

就像是:

var tos = new HashSet<string>(collection.Select(item => item.To));
var filtered = collection.Where(item => !tos.Contains(item.From));

你可能想检查一下,如果创建一个HashSet真的像这样工作,或者你是否需要以不同的方式构建它......但你明白了。集是有效的,如果tos变得相当长,因为你会检查这个很多......

于 2013-06-05T13:09:41.667 回答
1

假设您的对象集合如下:

var objects = { object1, object2, object3 }

然后你想要:

var result = objects.Where(o => !objects.Select(x => x.From).Contains(o.To));

如果它涉及大型数据集,缓存和存储“From”路径的子选择可能是明智的:

var fromPaths = new HashSet<string>(objects.Select(x => x.From));
var result = objects.Where(o => !fromPaths.Contains(o.To))
于 2013-06-05T13:10:24.897 回答
1

首先,您的示例与问题文本并不真正匹配,因为所有示例对象都有一个To对应于其他的From. 但是假设问题文本是正确的并且样本是错误的:

使用group-join怎么样:

var query = from obj in collection
            join fromObj in collection
                 on obj.To equals fromObj.From
                 into objGroup
            where !objGroup.Any()
            select obj;

或者,首先建立一组不同的 Froms:

var distinctFroms = new HashSet<string>(collection.Select(item => item.From));

var query = from obj in collection
            where !distinctFroms.Contains(obj.To)
            select obj;
于 2013-06-05T13:11:51.930 回答
0
var list = collection.Select(c=>c.To).Distinct().ToList();
var result = collection.Where(c=>!list.Contains(c.From)).ToList();
于 2013-06-05T13:10:06.253 回答
0

如果您使用 To 和 From 作为各自的键将集合重新连接到自身,则可以通过 To/From 确定哪些项目“加入”并排除它们:

var itemsThatAreConnected = 
    collection.Join(collection, x => x.To, x => x.From, (a,b) => a);
var unconnected = collection.Except(itemsThatAreConnected);
于 2013-06-05T13:10:32.100 回答